Python3学习之路~7.2 类的特殊成员方法

Posted zhengna

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 得票最高那个答案写的非常好

 

以上是关于Python3学习之路~7.2 类的特殊成员方法的主要内容,如果未能解决你的问题,请参考以下文章

7.2类

Python学习:17.Python面向对象(属性(特性),成员修饰符,类的特殊成员)

Python 学习笔记 - 面向对象(特殊成员)

python之路——面向对象(进阶篇)

python3学习之路(目录)

类的特殊成员方法