python中的__class__

##python中的__class__

__class__是类的一个内置属性,也是每个类实例的,它是一个类的引用。

self.__class__ is a reference to the type of the current instance.

简单例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'''类.__class__总是返回<type'type'>;实例.__class__返回实例所属的类的一个引用。'''
class A(object):
pass
>>> A.__class__
<type 'type'>
>>> a=A()
>>> a
<__main__.A object at 0x01B91690>
>>> a.__class__
<class '__main__.A'>
>>> a.__class__() #返回了类的一个新的实例
<__main__.A object at 0x01B915D0>
>>> A.__class__(A) #与A.__class__一样
<type 'type'>

可以从这里看到从CPython源码来分析__class__具体干了什么。

##__class__的用途

1.当一个类中的某个成员变量是所有该类的对象的公共变量时,可以用到__class__。
python代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A(object):
count = 0
def __init__(self):
self.__class__.count += 1
>>> A.count
0
>>> a=A()
>>> a.count
1
>>> b=A()
>>> b.count
2
>>> A.count
2

2.在类中返回该类的一个新实例,python的内置模块就有很多这样的应用。例如python的字符串对象,其中对字符串对象的很多操作都会返回字符串对象的一个新实例。
python代码:

1
2
3
4
5
6
7
8
9
10
def strip(self, chars=None):
return self.__class__(self.data.strip(chars))
def swapcase(self):
return self.__class__(self.data.swapcase())
def title(self):
return self.__class__(self.data.title())
def translate(self, *args):
return self.__class__(self.data.translate(*args))
def upper(self):
return self.__class__(self.data.upper())

更多代码细节其可查看这里

##__class的误用super(self.\class__, self)

使用super(self.class, self)会引发递归引用错误,针对py2,py3的super语法已经改了。
测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""Simple example showing why using super(self.__class__, self) is a BAD IDEA (tm)"""
class A(object):
def x(self):
print "A.x"
class B(A):
def x(self):
print "B.x"
super(B, self).x()
class C(B):
def x(self):
print "C.x"
super(C, self).x()
class X(object):
def x(self):
print "X.x"
class Y(X):
def x(self):
print "Y.x"
super(self.__class__, self).x() # <- this is WRONG don't do it!
class Z(Y):
def x(self):
print "Z.x"
super(self.__class__, self).x() # <- this is WRONG don't do it!
if __name__ == '__main__':
C().x()
Z().x() # will cause 'RuntimeError: maximum recursion depth exceeded'

更多讨论:(http://www.reddit.com/r/Python/comments/qa6g7/any_reason_not_to_use_self_class_with_super/)