类的特殊成员方法
类的特殊成员方法
1、__doc__ 表示类的描述信息
class Dog(object): '''这个是描述狗的一个类''' def __init__(self,name): self.name = name self.__weight = 100 def sayhi(self): print('my wigth is ', self.__weight,) d = Dog('二哈') print(d.__doc__) #这个是描述狗的一个类 print(Dog.__doc__) #这个是描述狗的一个类
2、__module__ 和 __class__
__module__ 表示当前操作的对象在哪个模块
__class__ 表示当前操作的对象是哪个类
3、__init__ 构造方法,类在实例化创建对象时,自动触发的方法
4、__del__ 析构方法 当对象在内存被释放时,自动触发执行。
5、__call__ 对象后面加括号,触发执行
class Dog(object): '''这个是描述狗的一个类''' def __init__(self,name): self.name = name self.__weight = 100 def sayhi(self): print('my wigth is ', self.__weight,) def __call__(self, *args, **kwargs): print('runing call',args,kwargs) d = Dog('二哈')
Dog('二哈')() #runing call () {}
d(1,2,3,4,5,name=888) #runing call (1, 2, 3, 4, 5) {'name': 888}
6、__dict__ 查看类或者对象中的所有成员
class Dog(object): '''这个是描述狗的一个类''' def __init__(self,name): self.name = name self.__weight = 100 def sayhi(self): print('my wigth is ', self.__weight,) def __call__(self, *args, **kwargs): print('runing call',args,kwargs) d = Dog('二哈') print(Dog.__dict__) #{'__dict__': <attribute '__dict__' of 'Dog' objects>, '__doc__': '这个是描述狗的一个类', '__init__': <function Dog.__init__ at 0x00000000010501E0>,
#'__call__': <function Dog.__call__ at 0x00000000010502F0>, 'sayhi': <function Dog.sayhi at 0x0000000001050268>, '__module__': '__main__',
#'__weakref__': <attribute '__weakref__' of 'Dog' objects>} #打印类里面的所有属性,不包括实例。 print(d.__dict__) #{'_Dog__weight': 100, 'name': '二哈'} 打印所有实例的属性,不包括类。
7、__str__ 如果一个类定义了__str__方法 ,那么在打印对象时。默认输出该方法的返回值
class Dog(object): '''这个是描述狗的一个类''' def __init__(self,name): self.name = name self.__weight = 100 def sayhi(self): print('my wigth is ', self.__weight,) def __call__(self, *args, **kwargs): print('runing call',args,kwargs) def __str__(self): return "obj:%s" % self.name d = Dog('二哈') d1 = Dog('秋田') print(d) # obj:二哈 print(d1) # obj:秋田
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__ k1 obj['k2'] = 'alex' # __setitem__ k2 alex del obj['k1'] # __delitem__ k1
9、__new__ \ __metaclass__
一切事物皆对象。
class Foo(object): def __init__(self,name): self.name = name f = Foo('alex') print(type(f)) #<class '__main__.Foo'> print(type(Foo)) #<class 'type'>
可以看到f是实例化Foo后的一个对象,不仅f是一个对象,Foo类本身也是一个对象。
f对象是Foo的一个实例,Foo类是type类的一个实例。说明Foo类是通过type类的构造方法创建。
那么,创建类就可以有两种方式:
1、普通方式
class Foo(object): def __init__(self,name): self.name = name f = Foo('alex')
2、特殊方式
def func(self): print('hello world') Foo = type('Foo',(),{'func':func}) #Foo表示要实例化之后的类,()表示要继承的类,func表示类里面的方法 print(type(Foo)) f= Foo() #<class 'type'> f.func() #hello world
既然可以通过这种方式创建类,并且可以添加类的方法,也可以把__init__这种方法装载进去。
def func(self): print('hello world') def __init__(self,name,age): self.name = name self.age = age Foo = type('Foo',(),{'func':func,'__init__':__init__}) #Foo表示要实例化之后的类,()表示要继承的类,func表示类里面的方法 f= Foo() #TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
这里提示实例化的时候__init__里面要传入两个参数。
def func(self): print('hello world') def __init__(self,name,age): self.name = name self.age = age Foo = type('Foo',(),{'func':func,'__init__':__init__}) #Foo表示要实例化之后的类,()表示要继承的类,func表示类里面的方法 f= Foo('alex','age') print(f.name,f.age) #alex age
那么,类默认是通过type类实例化产生,type类如何创建类?类又是如何创建对象的?
其实类中有一个属性 __metaclass__,其用来表示该类由谁来实例化创建的。所以可以为__metaclass__设置一个type类的派生类,从而查看类创建的过程。
1 class MyType(type): 2 def __init__(self,*args,**kwargs): 3 4 print("Mytype __init__",*args,**kwargs) 5 6 def __call__(self, *args, **kwargs): 7 print("Mytype __call__", *args, **kwargs) 8 obj = self.__new__(self) 9 print("obj ",obj,*args, **kwargs) 10 print(self) 11 self.__init__(obj,*args, **kwargs) 12 return obj 13 14 def __new__(cls, *args, **kwargs): 15 print("Mytype __new__",*args,**kwargs) 16 return type.__new__(cls, *args, **kwargs) 17 18 print('here...') 19 class Foo(object,metaclass=MyType): 20 21 22 def __init__(self,name): 23 self.name = name 24 25 print("Foo __init__") 26 27 def __new__(cls, *args, **kwargs): 28 print("Foo __new__",cls, *args, **kwargs) 29 return object.__new__(cls) 30 31 f = Foo("Alex") 32 print("f",f) 33 print("fname",f.name) 34 35 自定义元类
__new__()方法
class Foo(object): def __init__(self,name): self.name = name print("Foo __init__") def __new__(cls, *args, **kwargs): print("Foo __new__",cls, *args, **kwargs) return object.__new__(cls) f = Foo("Alex") #=========执行结果============ Foo __new__ <class '__main__.Foo'> Alex Foo __init__
实例化Foo类的时候会执行__init__,也会执行__new__。并且__new__会在__init__之前执行。
有一点不明白的是__new__()方法里面的return object.__new__(cls) 做什么用的?
尝试去掉这个return:
class Foo(object): def __init__(self,name): self.name = name print("Foo __init__") def __new__(cls, *args, **kwargs): print("Foo __new__",cls, *args, **kwargs) f = Foo("Alex") #=============执行结果============ Foo __new__ <class '__main__.Foo'> Alex
可以看到只执行了__new__()方法,并没有执行__init__这个方法。说明这个实例并没有真正被创建。
print(f.name) #AttributeError: 'NoneType' object has no attribute 'name'
说明__new__()用来创建实例的,object.__new__用父类的方法创建实例,那么传过去的cls做什么的?
cls 相当于self,也就是Foo,因为Foo也是一个对象,你要继承父类的东西就要把自己传过去。
print(object.__new__(cls)) #<__main__.Foo object at 0x0000000000A52320> #Foo内存对象
__metaclass__
1 class MyType(type): 2 def __init__(self,*args,**kwargs): 3 4 print("Mytype __init__",*args,**kwargs) 5 super(MyType, self).__init__( *args,**kwargs) 6 7 def __call__(self, *args, **kwargs): 8 print("Mytype __call__", *args, **kwargs) 9 #obj = self.__new__(self) 10 #self.__init__(obj,*args, **kwargs) 11 12 class Foo(object): 13 __metaclass__ = MyType 14 def __init__(self,name): 15 self.name = name 16 17 print("Foo __init__") 18 19 def __new__(cls, *args, **kwargs): 20 print("Foo __new__",cls, *args, **kwargs) 21 return object.__new__(cls) 22 23 f = Foo("Alex")
类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__
metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好