常用魔术方法总结

python 中常见的魔术方法:

1、__init__(self, item):方法

在实例化对象时自动执行,多用于对对象属性进行初始化。

2、__new__(cls,item):方法

实例化对象时自触发,在__init__ 方法之前执行,作为控制对象的生成过程,实现单例设计模式。

class Human:
  __instance = None
    def __init__(self, name):
        print('init method for {}'.format(name))

    def __new__(cls, *args,**kwargs):
    if cls.__instance is None:
      cls.__instance = object.__new__(Human)
    return cls.__instance

3、__del__(self):方法

对象被系统回收的时候自动触发(del不一定触发)

4、__getattr__(self, item): 方法
在访问对象的item属性的时候,如果对象和他的父类并没有这个相应的属性,方法,那么将会调用这个方法来处理。有相应的属性或方法时调用对象实例的相应属性或方法。
参数 item 代表 调用的属性或方法。

class Foo:
def __init__(self, x):
self.x = x

@property
def get_01(self):
print(111)
return self.x

def __getattr__(self, item):
# 当实例对象的的 f.a属性不存再时执行的操作
print('执行的是我')
print(item)
return self.x
f1 = Foo(10)
print(f1.get_01) # 111,10
print(f1.a) # 执行的是我 , a, 10
print(f1.get_02) # 执行的是我 , get_02, 10

5.__setattr__(self, item, value): 方法
会拦截所有属性的的赋值语句。如果定义了这个方法,self.arrt = value 就会变成self,__setattr__("attr", value).这个需要注意。
当在__setattr__方法内对属性进行赋值是,不可使用self.attr = value,因为他会再次调用self,__setattr__("attr", value),则会形成无穷递归循环,
最后导致堆栈溢出异常。应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__['name'] = value.

class Student:
def __init__(self,item):
self.x=item
def __getattr__(self, item):
return item + ' is not exits'

def __setattr__(self, key, value):
print("执行我")
self.__dict__[key] = value+2


s = Student(10) # # 调用__setattr__ 方法 执行我
print(s.x) # 12
print(s.name) # 调用__getattr__方法 输出'name is not exits'
s.age = 1 # 调用__setattr__ 方法
print(s.age) # 输出 3

6、__getattribute__(self,item):方法

访问成员属性时自动触发,无论成员属性是否存在

lass Human:

    def __init__(self):
        self.name = 'Python'
        self.sex = 'male'
        self.age = 18

    def __getattribute__(self, item):
        print('getattribute call by %s' % self)
        # return self.name   如果返回的是self.name,则会报错
        return super().__getattribute__(item)

    def eat(self):
        print('eat method is running')


human = Human()
print(human.name)

>>>>>>>>getattribute call by <__main__.Human object at 0x000001D633849240>
>>>>>>>>Python

7、__delattr__(sefl,item):方法

删除对象时自动执行,可以在删除对象时做一些其他工作

class Human:

    def __init__(self):
        self.name = 'Python'
        self.sex = 'male'
 
    def __delattr__(self, item):
        if item == 'name': # 当删除的对象成员名称为name时,不执行删除操作,即限制了删除name成员
            pass
        else:
            # del self.sex  如果执行此行,则会报错,递归数过大
            return super().__delattr__(item)

    def eat(self):
        print('eat method is running')


human = Human()
del human.name  # 不会删除name属性
del human.sex  # 会删除sex属性
print(human.name)
print(human.sex)

>>>>Python
>>>>AttributeError: 'Human' object has no attribute 'sex'

 

8、__str__(self): 方法 打印实例对象时 自动被调用
class Student:
  def __init__(self,item):
    self.x=item
  def __str__(self):
    print("打印对象时调用")
    return "111"

s=Student(10)
print(s) # 打印对象时调用 111

9、__len__(self):方法

使用 len检测对象的长度时自动触发

class Human:

    def __init__(self, name):
        self.name = name

    def __len__(self):
        # 必须有返回值,而且必须是整形
        return len(self.name)

human = Human('chengjie')
print(len(human)) #如果没有实现__len__, 则无法直接使用len(human), 否则报TypeError: object of type 'Human' has no len(), 实现了__len__后,可以根据需要

>>>>8

10、__call__(self,*args,**kwargs):方法

实例化对象当做函数调用时自动触发。

class MakeCake:

    def buy_yuan_liao(self):
        print('购买原料')

    def huo_mian(self):
        print('和面')

    def __call__(self, *args, **kwargs):
        self.buy_yuan_liao()
        self.huo_mian()
        print('蛋糕制作完成')


maek_cake = MakeCake() # 实例化一个类MakeCake的对象make_cake
maek_cake() # 把对象make_cake当做一个函数调用
>>>>购买原料
    和面
    蛋糕制作完成



posted @ 2019-08-14 17:52  wxl106  阅读(382)  评论(0编辑  收藏  举报