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 得票最高那个答案写的非常好

  • 相关阅读:
    Luogu3952 NOIP2017D1T2 时间复杂度
    Luogu4933 大师
    Luogu1966 火柴排队
    Luogu2881 排名的牛Ranking the Cows
    Luogu1439 最长公共子序列(LCS)
    Liferay7 BPM门户开发之20: 理解Asset Framework
    提高Liferay7的启动和运行速度
    liferay中jsonws的认证方法
    让Liferay的Service Builder连接其他数据库
    Liferay表结构介绍(四):Portlet相关表
  • 原文地址:https://www.cnblogs.com/zhengna/p/9618190.html
Copyright © 2011-2022 走看看