Python高阶---魔法方法

魔法方法:通过dir(函数名)查看到的方法中以双下划线开始,以双下划线结束的方法。

=========================================

class Student:
def init(self, name, age):
"""
负责初始化类的实例,实例是由__new__方法传递过来的,也就是这里的self
:param name:
:param age:
"""
self.name = name
self.age = age
self.f = open('./txt/1.txt')

def __repr__(self):
    """
    类的自我描述
    一般形式为:类名[attr]=value
    :return:
    """
    return 'Student[name=' + self.name+', age=' + str(self.age) + ']'

def __del__(self):
    """
    自动销毁、删除对象
    :return:
    """
    print('__del__方法被调用')
    self.f.close()

stu = Student('zhangsan', 18)
print(stu)
print(stu.repr())

==================================

class Students:
def new(cls, *args, **kwargs):
"""
负责创建类的实例
:param args:
:param kwargs:
"""
print('__new__方法被调用')
return object.new(cls)

def __init__(self, name, age):
    """
    负责初始化类的实例,实例是由__new__方法传递过来的,也就是这里的self
    :param name:
    :param age:
    """
    print('__init__方法被调用')
    self.name = name
    self.age = age

stus = Students('zhangsan', 18)
print(stus)

==================================

class NewInt(int):
def new(cls, value):
print('__new__方法被调用')
return int.new(cls, abs(value))

a = NewInt(-4.56)
print(a)

==================================

实现类的单例模式

class Student1:
__isinstance = False # 保存我们已经创建好的实例
def new(cls, value):
if not cls.__isinstance: # 没有创建过任何实例
cls.__isinstance = object.new(cls)
return cls.__isinstance # 如果有实例,则直接返回实例

def __init__(self, name):
    """
    负责初始化类的实例,实例是由__new__方法传递过来的,也就是这里的self
    :param name:
    """
    print("我是{}。".format(name))

stu1 = Student1('zhangsan') # 内存地址相同
stu2 = Student1('lisi') # 内存地址相同

==========================================

属性管理

dir(): 查看对象的方法和属性的名字
dir(): 是一个函数, 查看属性
print(dir([])) # 查看列表有哪些属性

==================================

属性管理

dir(): 查看对象的方法和属性的名字

dir(): 是一个函数, 查看属性

print(dir([]))

class Students2:

def __init__(self, name, age):
    """
    负责初始化类的实例,实例是由__new__方法传递过来的,也就是这里的self
    :param name:
    :param age:
    """
    print('__init__方法被调用')
    self.name = name
    self.__age = age   # 私有属性

stus2 = Students2('zhangsan', 18)
print(dir(stus2))
print(stus2._Students2__age) # 可以查看私有属性
print(dir(Students2))
print(stus2.dict) # 作用于对象时,只打印该对象拥有的所有属性名和属性值,包含私有属性
print(Students2.dict) # 作用于类时,只打印共享的类属性以及类的所有方法
print(stus2.dict['name']) #
stus2.dict['name'] = 'lisi' # 设置name的值
stus2.dict['id'] = 's001' # 动态增加属性
print(stus2.id)

==================================

__getattribute__属性:访问对象的任意属性时被自动调用

class Students3:
def init(self, name, age):
"""
:param name:
:param age:
"""
print('__init__方法被调用')
self.name = name
self.age = age

def __getattribute__(self, item):
    try:
        print('__getattribute__方法被调用了,调用的属性为:', item)
        # return self.name   # 会造成死循环
        return super().__getattribute__(item)

    except AttributeError as e:
        print(e)
        print('访问了未定义属性,请检查')

stu3 = Students3('zhangsan', 18)
stu3.name
stu3.xxx

==============================

class Students3:
    def __init__(self, name, age):
        """
        :param name:
        :param age:
        """
        print('__init__方法被调用')
        self.name = name
        self.age = age
    def show(self):
        print(123)

    def __getattr__(self, item):   # __getattr__当访问不存在对象或属性时被触发
        print('--->', item)
        return 789

==============================

__setattr__当对xxx属性赋值时被调用

__delattr__当删除对象的xxx属性时被调用

class Students5:

def __init__(self, name, age):
    """
    :param name:
    :param age:
    """
    print('__init__方法被调用')
    self.name = name
    self.age = age

def __getattribute__(self, item):
    try:
        print('__getattribute__方法被调用了,调用的属性为:', item)
        # return self.name   # 会造成死循环
        return super().__getattribute__(item)

    except AttributeError as e:
        print(e)
        print('访问了未定义属性,请检查')
        return 'default'

    # print('调用了{}属性:'.format(item))
    # return super().__getattribute__(item)

def __getattr__(self, item):
    # 当__getattribute__没有处理AttributeError的时候,python会调用重写的__getattr__
    print('__getattr__方法被调用了', item)

def __setattr__(self, key, value):
    print('程序设置属性{}'.format(key))
    if key == 'age':
        if value < 18:
            raise Exception('age的值必须大于等于18')
        else:
            self.__dict__[key] = value   # 这句必须写,保证当属性的值正确时可以赋值给属性
    else:
        self.__dict__[key] = value

def __delattr__(self, item):
    print('__delattr__被调用')

stu5 = Students5('zhangsan', 18)
print(stu5.name)
stu5.name = 'lisi'
stu5.age = 20
print(stu5.age)
del stu5.age

=====================================

posted @ 2024-05-06 11:33  星空28  阅读(6)  评论(0编辑  收藏  举报