zoukankan      html  css  js  c++  java
  • Python3学习之路~7.2 类的特殊成员方法

    1. __doc__ 表示类的描述信息

    class Dog(object):
        """ 这个类是描述狗这个对象的 """
        def func(self):
            pass
    
    print(Dog.__doc__)
    # 输出: 这个类是描述狗这个对象的
    

    2. __module__ 和  __class__ 

      __module__ 表示当前操作的对象在哪个模块

      __class__     表示当前操作的对象的类是什么

    class C:
    
        def __init__(self):
            self.name = 'aa'
    lib/aa.py
    from lib.aa import C
    
    obj = C()
    print obj.__module__  # 输出 lib.aa,即:输出模块
    print obj.__class__      # 输出 lib.aa.C,即:输出类
    index

    3. __init__ 构造方法,通过类创建对象时,自动触发执行。

    4.__del__ 析构方法,当对象在内存中被释放时,自动触发执行。

    5. __call__ 对象后面加括号,触发执行。

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
    class Foo:
        def __init__(self):
            print("__init__")
    
        def __call__(self, *args, **kwargs):
            print('__call__')
    
    obj = Foo()  # 执行 __init__
    obj()  # 执行 __call__
    

    6. __dict__ 查看类或对象中的所有成员   

    class Province:
        country = 'China'
    
        def __init__(self, name,count):
            self.name = name
            self.count = count
        def func(self):
            print("func")
    
    # 获取类的成员,不包括实例属性
    print(Province.__dict__)
    # 输出:
    # {'__module__': '__main__', 'country': 'China', '__init__': <function Province.__init__ at 0x00000000027EA9D8>, 
    # 'func': <function Province.func at 0x00000000027EAA60>, '__dict__': <attribute '__dict__' of 'Province' objects>, 
    # '__weakref__': <attribute '__weakref__' of 'Province' objects>, '__doc__': None}
    
    # 获取 对象obj1 的成员,不包括类属性
    obj1 = Province("shandong",1000)
    print(obj1.__dict__)
    # 输出:{'name': 'shandong', 'count': 1000}
    

    7.__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

    class Foo:
         def __str__(self):
            return 'alex li'
      
    obj = Foo()
    print obj
    # 输出:alex li
    

    8.__getitem__、__setitem__、__delitem__

    用于索引操作,如字典。以上分别表示获取、设置、删除数据

    class Foo(object):
        def __getitem__(self, key):
            print('__getitem__', key)
    
        def __setitem__(self, key, value):
            print('__setitem__', key, value)
    
        def __delitem__(self, key):
            print('__delitem__', key)
    
    obj = Foo()
    result = obj['k1']  # 自动触发执行 __getitem__
    obj['k2'] = 'alex'  # 自动触发执行 __setitem__
    del obj['k1'] # 自动触发执行__delitem__
    

    可用于写一个类 封装属于自己的字典,django里面会用到它,用来封装自己的一些底层的东西,用户以为自己是调用的字典,其实是调用的实例。可以对某些key加一些限制,达到使用户可以访问字典,却不能对其进行删除的目的。

    9. __new__ __metaclass__

    class Foo(object): 
        def __init__(self,name):
            self.name = name
     
    f = Foo("Alex")
    

    上述代码中,f 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

    如果按照一切事物都是对象的理论:f 对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

    print(type(f)) # 输出:<class '__main__.Foo'>     表示,f 对象由 Foo 类创建
    print(type(Foo)) # 输出:<type 'type'>            表示,Foo类对象由 type 类创建
    

    所以,f对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

    那么,创建类就可以有两种方式:

    a). 普通方式 

    class Foo(object):
    
        def talk(self):
            print('hello Alice')
    

    b). 特殊方式

    def talk(self):
            print('hello Alice')
    
    Foo = type('Foo', (object,), {'talk': talk}) 
    #注意:这里的(object,)是元组的形式,必须后面加一个逗号,如果不加,Python会认为(object)是一个值
    def talk(self):
        print("hello %s" % self.name)
    
    def __init__(self,name,age):
        self.name = name
        self.age = age
    
    Foo = type("Foo",(object,),{"talk":talk,"__init__":__init__})
    加上构造方法

    So ,记住,类 是由 type 类实例化产生

    那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

    答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

    class MyType(type):
        def __init__(self,*args,**kwargs):
            print("Mytype __init__")
    
        def __call__(self, *args, **kwargs):
            print("Mytype __call__")
            obj = self.__new__(self)
            self.__init__(obj,*args, **kwargs)
    
        def __new__(cls, *args, **kwargs):
            print("Mytype __new__")
            return type.__new__(cls, *args, **kwargs)
    
    class Foo(object,metaclass = MyType):
        # __metaclass__ = MyType
        def __init__(self,name):
            self.name = name
            print("Foo __init__")
    
        def __new__(cls, *args, **kwargs):
            print("Foo __new__")
            return object.__new__(cls)
    
    f = Foo("Alex")
    
    # 输出:
    # Mytype __new__
    # Mytype __init__
    # Mytype __call__
    # Foo __new__
    # Foo __init__
    类创建的过程

     类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

     metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好

  • 相关阅读:
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    软件工程实践总结
  • 原文地址:https://www.cnblogs.com/zhengna/p/9618190.html
Copyright © 2011-2022 走看看