zoukankan      html  css  js  c++  java
  • 魔术方法--?

    方法:

      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__,避免重复调用。
  • 相关阅读:
    【转发】JS中如何判断null/ undefined/IsNull
    CSS3实现两行或三行文字,然后多出的部分省略号代替
    关于CodeFirst的使用教程
    把一个字符串里符合表情文字标签的地方全部替换为相应的图片的方法
    js 给json添加新的字段,或者添加一组数据,在JS数组指定位置删除、插入、替换元素
    用css3选择器给你要的第几个元素添加不同样式方法【转发】
    WebApi2 知识点总结
    把字符串每隔四个字符使用“-”中横线分隔的方法
    C语言strchr()函数:查找某字符在字符串中首次出现的位置
    linux 下安装开发组件包
  • 原文地址:https://www.cnblogs.com/yifengs/p/11438339.html
Copyright © 2011-2022 走看看