6、第六 - 面向对象高级语法-类的特殊成员方法
class类中,特殊成员的调用方法介绍。
1、__doc__ 表示类的描述信息
class Foo(object):
"""注析:描述类信息,很是神奇 """
def fun(self):
pass
print(Foo.__doc__) #调用,打印注析文档。
输出:
注析:描述类信息,很是神奇
2、__module__ 与 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
第一步:参考上个例子,并且命名为:Ok.py
class FOO(object):
"""注析:描述类信息,很是神奇 """
def fun(self):
pass
print(FOO.__doc__) #调用输出注析文档
第二步:写另外一个调用的模块,并且命名为:modAndclass.py
from Ok import FOO
obj = FOO()
print (obj.__module__) #输出OK,即输出模块
print (obj.__class__) #输出OK.Foo,即输出类的名字
输出:
注析:描述类信息,很是神奇
Ok
<class 'Ok.FOO'>
3、__init__ 类中的构造函数,通过类创建对象时,自动触发执行。
举例:
class Name(object):
def __init__(self,name):
self.name = name
def talk(self):
print("%s talking ......" % self.name)
w = Name("chen1203")
w.talk()
输出:
chen1203 talking ......
4、__del__ 析构方法,当对象在内存中被释放时,自动触发执行。
备注:此方法一般无须定义,开发使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
5、__call__ 对象后面加括号,触发执行。
备注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()。
举例:
class Name:
def __init__(self,name):
self.name = name
def talk(self):
print("%s talking ......" % self.name)
w = Name("chen1203")
w.talk() #正常的调用方式
w() #使用此方法调用就会报错。
输出如下:
chen1203 talking ......
Traceback (most recent call last):
File "/Users/mac/PycharmProjects/untitled2/51CTO/6day/modAndclass.py", line 11, in <module>
w()
TypeError: 'Name' object is not callable
要想上面例子中,w() 可以正常的调用。要添加__call__函数,修改如下;
例1:使用w()直接调用
class Name:
def __init__(self,name):
self.name = name
def talk(self):
print("%s talking ......" % self.name)
def __call__(self, *args, **kwargs):
print ("%s call me " % self.name)
w = Name("chen1203")
w.talk()
w()
输出:
chen1203 talking ......
chen1203 call me
例2:使用w("qing") 传入参数
class Name:
def __init__(self,name):
self.name = name
def talk(self):
print("%s talking ......" % self.name)
def __call__(self, *args, **kwargs):
print (" call me ",args,kwargs)
w = Name("chen1203")
w.talk()
w('1','2','3','chen',mingzi="qing1203" )
输出:
chen1203 talking ......
call me ('1', '2', '3', 'chen') {'mingzi': 'qing1203'}
备注:w()传入参数之后, 会按照元组、字典的方式打印出来。
6、__dict__ 查看类或对象中的所有成员。
举例:
class Name(object):
country = "China"
def __init__(self,name,count):
self.name = name
self.count = count
def talk(self):
print("%s talking ......" % self.name)
def __call__(self, *args, **kwargs):
print ("call me ",args,kwargs)
#获取类的成员,即静态字段、函数构造方法的都有哪些。
print (Name.__dict__)
#输出:{'__dict__': <attribute '__dict__' of 'Name' objects>, '__doc__': None, '__call__': <function Name.__call__ at 0x10217aea0>, '__init__': <function Name.__init__ at 0x10217a9d8>, '__weakref__': <attribute '__weakref__' of 'Name' objects>, 'talk': <function Name.talk at 0x10217aa60>, '__module__': '__main__', 'country': 'China'}
#获取obj的成员
obj = Name("beijing",1203)
print (obj.__dict__)
#输出 :{'name': 'beijing', 'count': 1203}
7、__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
举例:
class Name:
country = "China"
def __init__(self,name,count):
self.name = name
self.count = count
def talk(self):
print("%s talking ......" % self.name)
def __call__(self, *args, **kwargs):
print ("call me ",args,kwargs)
def __str__(self):
print ("name is %s " % self.name)
return "qing1203"
obj = Name("chen1203",1234)
print (obj) #默认会调用输出 __str__ 方法中的返回值
输出:
name is chen1203
qing1203
8、__getitem__、__setitem__、__delitem__ 用于索引操作,如字典。以上分别表示获取、设置、删除数据
举例:
class Foo(object):
def __init__(self):
self.data = {}
def __getitem__(self, key):
print('__getitem__', key)
def __setitem__(self, key, value):
print('__setitem__', key, value)
self.data[key] = value
def __delitem__(self, key):
print('__delitem__', key)
obj = Foo()
obj["chen"] = "1203" #添加字典类目,默认调用setitem方法
obj["qing"] = "1204" #添加字典类目,默认调用setitem方法
print (obj.data) #把字典中的信息,也全部打印
del obj["qing"] #其实,没有真正意义上的删除。
print (obj.data) #把字典中的信息,也全部打印了
print (obj.data["qing"]) #调出为qing, 的value值
输出:
__setitem__ chen 1203
__setitem__ qing 1204
{'qing': '1204', 'chen': '1203'}
__delitem__ qing
{'qing': '1204', 'chen': '1203'}
1204
备注:python2.7版本里面,可以把实例变成列表;python3 版本里面就是没这个方法了
9、__new__ 、 __metaclass__
class Foo(object):
def __init__(self, name):
self.name = name
f = Foo("alex")
print (type(f)) # 输出:<class '__main__.Foo'> 表示,f 对象由Foo类创建
print (type(Foo))# 输出:<type 'type'> 表示,Foo类对象由 type 类创建
输出:
<class '__main__.Foo'>
<class 'type'>
上述代码中,f 是通过 Foo 类实例化的对象,其实,不仅 f 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。
f 对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法创建。所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。
创建类就可以有两种方式:
1)、普通方法创建:
class Foo(object):
def __init__(self, name):
self.name = name
def func(self):
print('hello world')
f = Foo("alex") #创建对象,实例化类
2)、特殊方式(装B方式)
def func(self):
print("hello world %s" % self.name)
def __init__(self,name,age):
self.name = name
self.age = age
F = type('Foo1',(object,),{'talk':func,'__init__':__init__})
#type第一个参数:类名,注:(object,) 括号里面的object必须要跟一个逗号
#type第二个参数:当前类的基
#type第三个参数:类的成员
ok = F("chen",1203)
ok.talk()
输出:
hello world chen
注:类是由 type 类实例化产生。
下面,先介绍 __new__的使用方法: 就是用来创建实例的.在__init__之前创建方法。
举例:
class Foo(object):
def __init__(self,name):
self.name = name
print("Foo __init__",self.name)
def __new__(cls, *args, **kwargs):
print("Foo __new__",cls, *args, **kwargs)
return object.__new__(cls) #继承父类的__new__方法
obj = Foo("chen1203")
输出:
Foo __new__ <class '__main__.Foo'> chen1203
Foo __init__ chen1203
#执行顺序为:new --> init 。先执行的new,再把底参数上传到init的self中传参。
如果修改了下下面的对象调用后:
obj = Foo("chen1203",1234,"fasfa")
输出信息为:
Foo __new__ <class '__main__.Foo'> chen1203 1234 fasfa #new的执行是成功的
Traceback (most recent call last):
File "/Users/mac/PycharmProjects/untitled2/51CTO/6day/newAndmetathod.py", line 12, in <module>
obj = Foo("chen1203",1234,"fasfa")
TypeError: __init__() takes 2 positional arguments but 4 were given
类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?
类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。
举例1: 不添加 __metaclass__
举例1:
class MyType(type):
def __init__(self, *args, **kwargs):
print("Mytype __init__", *args, **kwargs)
def __call__(self, *args, **kwargs):
print("Mytype __call__", *args, **kwargs)
obj = self.__new__(self)
print("obj ", obj, *args, **kwargs)
print(self)
self.__init__(obj, *args, **kwargs)
return obj
def __new__(cls, *args, **kwargs):
print("Mytype __new__", *args, **kwargs)
return type.__new__(cls, *args, **kwargs)
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("chen1203")
print("f", f)
print("fname", f.name)
输出:
Foo __init__
f <__main__.Foo object at 0x102194438>
fname chen1203
注:不会调用到上到上面的 MyType. ...因为没有类的继承。
举例2: 添加 __metaclass__ 由 MyType 类创建实例化
class MyType(type):
def __init__(self, *args, **kwargs):
print("Mytype __init__", *args, **kwargs)
def __call__(self, *args, **kwargs):
print("Mytype __call__", *args, **kwargs)
obj = self.__new__(self)
print("obj ", obj, *args, **kwargs)
print(self)
self.__init__(obj, *args, **kwargs)
return obj
def __new__(cls, *args, **kwargs):
print("Mytype __new__", *args, **kwargs)
return type.__new__(cls, *args, **kwargs)
class Foo(object, metaclass=MyType): #或者写到下面 像__metaclass__ = MyType
#__metaclass__ = MyType
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("chen1203")
print("f", f)
print("fname", f.name)
输出:
Mytype __new__ Foo (<class 'object'>,) {'__new__': <function Foo.__new__ at 0x101995048>, '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x10197af28>, '__module__': '__main__'}
Mytype __init__ Foo (<class 'object'>,) {'__new__': <function Foo.__new__ at 0x101995048>, '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x10197af28>, '__module__': '__main__'}
Mytype __call__ chen1203
Foo __new__ <class '__main__.Foo'>
obj <__main__.Foo object at 0x101994470> chen1203
<class '__main__.Foo'>
Foo __init__
f <__main__.Foo object at 0x101994470>
fname chen1203
注意:打印的执行顺序 Mytype __new__ --> Mytype __init__ --> Mytype __call__ -->Foo __new__ --> Foo __init__
结论:类的生成 调用 顺序依次是: __new__ --> __init__ --> __call__
如图解析

浙公网安备 33010602011771号