类的特殊成员方法

类的特殊成员方法

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 自定义元类
View Code

__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")
View Code

 类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

 metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好

 

posted on 2017-08-27 00:20  老榕树下的咖啡屋  阅读(177)  评论(0编辑  收藏  举报