类的特殊成员方法
类的特殊成员方法
1. __doc__ 表示类的描述信息
class Foo(object): """ 类的描述信息 """ def func(self): pass print(Foo.__doc__) #执行结果 类的描述信息
2.__module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
#lib文件夹下的aa.py文件 class C: def __init__(self): self.name = 'Mike'
#与lib文件夹同级 from lib.aa import C obj=C() print(obj.__module__) print(obj.__class__) #执行结果 lib.aa <class 'lib.aa.C'>
3. __init__ 构造方法,通过类创建对象时,自动触发执行。
4.__del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
5. __call__ 对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print ('__call__') obj = Foo() # 执行 __init__ obj() # 执行 __call__ #执行结果 __call__
6. __dict__ 查看类或对象中的所有成员
class Province: country = 'China' def __init__(self, name, count): self.name = name self.count = count def func(self, *args, **kwargs): print('func') # 获取类的成员,即:静态字段、方法、 print(Province.__dict__) obj1 = Province('HeBei', 10000) # 获取 对象obj1 的成员 print(obj1.__dict__) obj2 = Province('HeNan', 3888) # 获取 对象obj2的成员 print(obj2.__dict__) #执行结果: {'__weakref__': <attribute '__weakref__' of 'Province' objects>, 'func': <function Province.func at 0x011C3300>, '__init__': <function Province.__init__ at 0x011C3270>, '__module__': '__main__', 'country': 'China', '__dict__': <attribute '__dict__' of 'Province' objects>, '__doc__': None} 'name': 'HeBei', 'count': 10000} {'name': 'HeNan', 'count': 3888}
7.__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
class Foo: def __str__(self): return 'Mike' obj = Foo() print(obj) #执行结果 Mike
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'] = 'Mike' # 自动触发执行 __setitem__ del obj['k1'] #执行结果 __getitem__ k1 __setitem__ k2 Mike __delitem__ k1
9. __new__ \ __metaclass__
class Foo(object): def __init__(self, name): self.name = name f = Foo("Mike")
上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。
如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。
print(type(f)) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建 print (type(Foo)) # 输出:<type 'type'> 表示,Foo类对象由 type 类创建
所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。
那么,创建类就可以有两种方式:
a). 普通方式
class Foo(object): def func(self): print('Hello world!')
b). 特殊方式
def func(self): print( 'hello world') Foo = type('Foo', (object,), {'func': func}) # type第一个参数:类名 # type第二个参数:当前类的基类 # type第三个参数:类的成员
def func(self): print("hello %s"%self.name) def __init__(self,name,age): self.name = name self.age = age Foo = type('Foo',(object,),{'func':func,'__init__':__init__}) f = Foo("jack",22) f.func() 加上构造方法
So ,类 是由 type 类实例化产生
那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?
答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。
#_*_coding:utf-8_*_ class MyType(type): def __init__(self, child_cls, bases=None, dict=None): print("--MyType init---", child_cls,bases,dict) #super(MyType, self).__init__(child_cls, bases, dict) # def __new__(cls, *args, **kwargs): # print("in mytype new:",cls,args,kwargs) # type.__new__(cls) def __call__(self, *args, **kwargs): print("in mytype call:", self,args,kwargs) obj = self.__new__(self,args,kwargs) self.__init__(obj,*args,**kwargs) class Foo(object,metaclass=MyType): #in python3 #__metaclass__ = MyType #in python2 def __init__(self, name): self.name = name print("Foo ---init__") def __new__(cls, *args, **kwargs): print("Foo --new--") return object.__new__(cls) def __call__(self, *args, **kwargs): print("Foo --call--",args,kwargs) # 第一阶段:解释器从上到下执行代码创建Foo类 # 第二阶段:通过Foo类创建obj对象 obj = Foo("Alex") #print(obj.name) 自定义元类
类的生成 调用 顺序依次是 __new__ --> __call__ --> __init__
metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好