魔术方法--?

方法:

  1 # -*- coding:utf-8 -*-
  2 # 1.__doc__  表示类的描述信息
  3 class Foo(object):
  4     """ 描述类信息1234 """
  5     def func(self):
  6         pass
  7 print(Foo.__doc__)  # 描述类信息1234
  8 
  9 # 2.__module__  表示当前操作的对象在那个模块
 10 #   __class__  表示当前操作的对象的类是什么
 11 from test import Person
 12 
 13 obj = Person()
 14 print(obj.__module__)  # 输出test  模块名
 15 print(obj.__class__)  # 输出Person 类名
 16 
 17 # 3.__init__  初始化方法,通过类创建对象时,自动触发执行  和__new__一起组成构造方法
 18 class Person(object):
 19     def __init__(self,name):
 20         self.name = name
 21         self.age = 18
 22 
 23 obj = Person("小明")  # 自动执行类里面的__init__方法
 24 
 25 # 4.__del__  当对象被销毁(即在内存中被释放)的时候,自动触发执行
 26 # 注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,__del__的调用是由解释器在进行垃圾回收时自动触发执行的。
 27 class Foo(object):
 28     def __del__(self):
 29         pass
 30 
 31 # 5.__call__ 实例化对象后面加括号,直接出发执行
 32 class Foo(object):
 33     def __init__(self):
 34         pass
 35 
 36     def __call__(self, *args, **kwargs):
 37         print('__call__')
 38 
 39 
 40 obj = Foo()  # 执行 __init__
 41 obj()  # 执行 __call__
 42 
 43 # 6.__dict__  查看类或对象中所有的属性
 44 class Province(object):
 45     country = "中国"
 46 
 47     def __init__(self,name,count):
 48         self.name = name
 49         self.count = count
 50 
 51     def func(self,*args,**kwargs):
 52         print("func")
 53 
 54 print(Province.__dict__)
 55 #输出类的属性和方法:{'__weakref__': <attribute '__weakref__' of 'Province' objects>, '__module__': '__main__', 'country': '中国', 'func': <function Province.func at 0x0000019BB5280400>, '__dict__': <attribute '__dict__' of 'Province' objects>, '__init__': <function Province.__init__ at 0x0000019BB5280598>, '__doc__': None}
 56 obj = Province("山东",100)
 57 print(obj.__dict__)  # 输出实例化对象的属性: {'count': 100, 'name': '山东'}
 58 
 59 # 7.__str__  如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值 如果没有这个方法 输出的是对象的地址
 60 class Foo(object):
 61     def __str__(self):
 62         return "---Foo---"
 63 
 64 class Foo2(object):
 65     pass
 66 
 67 obj1 = Foo()
 68 obj2 = Foo2()
 69 print(obj1)  # 输出: ---Foo---
 70 print(obj2)  # 输出: <__main__.Foo2 object at 0x000001907FEC75F8>
 71 
 72 # 8.__getitem__、__setitem__、__delitem__
 73 # 用于索引操作,如字典。以上分别表示获取、设置、删除数据
 74 class Foo(object):
 75     def __setitem__(self, key, value):
 76         self.key = key
 77         self.value = value
 78         print("设置完毕")
 79 
 80     def __getitem__(self, key):
 81         print("key:%s--->value:%s" % (key,self.value))
 82 
 83     def __delitem__(self, key):
 84         del key
 85 
 86 obj = Foo()
 87 obj["k1"] = 100  # 自动触发执行 __setitem__ 输出:设置完毕
 88 print(obj["k1"])  # 自动触发执行 __getitem__ 输出:key:k1--->value:100
 89 del obj["k1"]  # 自动触发执行 __delitem__ 输出:None
 90 print(obj["k1"]) # 输出:key:k1--->value:100 ?? 怎么删除了还能输出这个 没理解
 91                         # None
 92 
 93 # 9.__getslice__、__setslice__、__delslice__
 94 # 该三个方法用于分片操作,如:列表
 95 # 注:此方法只能在python2.x中使用,python3.x中报错 也必须要有utf-8的编码格式
 96 # -*- coding:utf-8 -*-
 97 class Foo(object):
 98     save_list = [1,2,3,4,5,6]
 99     def __getslice__(self, i, j):
100         print('__getslice__')
101         return self.save_list[i:j]
102 
103     def __setslice__(self, i, j, sequence):
104         print('__setslice__')
105         self.save_list[i:j] = sequence
106         print(self.save_list)
107 
108     def __delslice__(self, i, j):
109         print('__delslice__')
110         del self.save_list[i:j]
111         print(self.save_list)
112 
113 obj = Foo()
114 result = obj[0:3]  # 自动触发执行 __getslice__ 输出:__getslice__
115 print(result)  # 输出: [1, 2, 3]
116 obj[0:1] = [11,22,33,44]    # 自动触发执行 __setslice__ 输出:__setslice__
117                                                         # [11, 22, 33, 44, 2, 3, 4, 5, 6]
118 del obj[0:2]                # 自动触发执行 __delslice__ 输出:__delslice__
119                                                         # [33, 44, 2, 3, 4, 5, 6]

 __getattr__、__setattr__、__delattr__:

1、__getattr__
当我们访问一个不存在的属性的时候,会抛出异常,提示我们不存在这个属性。而这个异常就是__getattr__方法抛出的,其原因在于他是访问一个不存在的属性的最后落脚点,作为异常抛出的地方提示出错再适合不过了。

看例子,我们找一个存在的属性和不存在的属性。

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __getattr__(self, item):
        print "into __getattr__"
        return  "can not find"
 
a = A(10)
print a.value
# 10
print a.name
# into __getattr__
# can not find
可以看出,访问存在的属性时,会正常返回值,若该值不存在,则会进入最后的兜底函数__getattr__。

2、__setattr__
在对一个属性设置值的时候,会调用到这个函数,每个设置值的方式都会进入这个方法。

class A(object):
    def __init__(self, value):
        print "into __init__"
        self.value = value
 
    def __setattr__(self, name, value):
        print "into __setattr__"
        if value == 10:
            print "from __init__"
        object.__setattr__(self, name, value)
 
 
a = A(10)
# into __init__
# into __setattr__
# from __init__
print a.value
# 10
a.value = 100
# into __setattr__
print a.value
# 100
在实例化的时候,会进行初始化,在__init__里,对value的属性值进行了设置,这时候会调用__setattr__方法。

在对a.value重新设置值100的时候,会再次进入__setattr__方法。

需要注意的地方是,在重写__setattr__方法的时候千万不要重复调用造成死循环。

比如:

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __setattr__(self, name, value):
        self.name = value
这是个死循环。当我们实例化这个类的时候,会进入__init__,然后对value进行设置值,设置值会进入__setattr__方法,而__setattr__方法里面又有一个self.name=value设置值的操作,会再次调用自身__setattr__,造成死循环。

除了上面调用object类的__setattr__避开死循环,还可以如下重写__setattr__避开循环。

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __setattr__(self, name, value):
        self.__dict__[name] = value
 
 
a = A(10)
print a.value
# 10
3、__delattr__
__delattr__是个删除属性的方法

class A(object):
    def __init__(self, value):
        self.value = value
 
    def __delattr__(self, item):
        object.__delattr__(self, item)
 
    def __getattr__(self, item):
        return "when can not find attribute into __getattr__"
 
 
 
a = A(10)
print a.value
# 10
del a.value
print a.value
# when can not find attribute into __getattr__
__delattr__也要避免死循环的问题,就如__setattr__一样,在重写__delattr__,避免重复调用。
原文地址:https://www.cnblogs.com/yifengs/p/11438339.html