class Employee:
def setname(self, who):
self.name = who
def display(self):
print self.name
self相当于C++中的this指针。C++的this指针是隐含的,但Python中self是需要显示地写出。
2. Python 把对象(object)分为class object和instance object。每个类型都有一个对象,该对象能生成多个实例对象。
3. 可以通过类型对象或者实例对象调用类型的方法。比如下列两种调用setname的方式是等价的:
e = Employee()
e.setname('Harry')
Employee.setname(e, 'Harry')
4. 实例对象的成员变量不需要提前声明,它们在赋值时自动创建。
5. 可以在类型定义之外为实例对象添加新的成员变量,比如:
e.lastname = 'He'
6. 可以在类型定义之外为类型添加新的成员函数,比如:
def upperName(self):
return self.name.upper()
Employee.method = upperName
e.method()
7. 如果子类没有重写__init__,会自动调用父类的__init__函数:
class A:
def __init__(self):
print 'A is instantiated'
class B (A):
pass
if __name__ == '__main__':
b = B()
此时A.__init__仍然会被调用
如果子类重写了__init__函数,父类的__init__函数不会自动自动被调用,如以下代码:
class A:
def __init__(self):
print 'A is instantiated'
class B (A):
def __init__(self):
print 'B is instantiated'
if __name__ == '__main__':
b = B()
如果希望父类的__init__函数被调用,需要在子类的__init__函数里显示地调用:如以下代码:
class A:
def __init__(self):
print 'A is instantiated'
class B (A):
def __init__(self):
A.__init__(self)
print 'B is instantiated'
if __name__ == '__main__':
b = B()
8. Python的class不支持类似于C++/C#/Java的static函数/方法
9. metaclass可以用来生成新的class。详细讨论可以参考http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python。
10. static变量和实例的变量:
>>> class Test(object):
... i = 3
...
>>> Test.i
3
>>> t = Test()
>>> t.i # static variable accessed via instance
3
>>> t.i = 5 # but if we assign to the instance ...
>>> Test.i # we have not changed the static variable
3
>>> t.i # we have overwritten Test.i on t by creating a new attribute t.i
5
>>> Test.i = 6 # to change the static variable we do it by assigning to the class
>>> t.i
5
>>> Test.i
6
11.在Python中没有类似于C/C++/C#的enum类型。下面是几种用Python模拟enum的方法:
(1) 生成新的type:
def enum(**enums):
return type('Enum', (), enums)
>>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'
或者自动编号:
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
>>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1
如果需要逆向查找:
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
reverse = dict((value, key) for key, value in enums.iteritems())
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)
>>> Numbers.reverse_mapping['three']
'THREE'
(2)基于set:
class Enum(set):
def __getattr__(self, name):
if name in self:
return name
raise AttributeError
Animals = Enum(["DOG", "CAT", "HORSE"])
print Animals.DOG
(3)基于tuple:
(Pen, Pencil, Eraser) = range(0, 3)
或者:
class Stationery:
(Pen, Pencil, Eraser) = range(0, 3)
12. 如果类型需要支持+、-、×、/,则需要添加__add__、__sub__、__mul__、__rmul__、__div__等。如果需要支持比较,则需要添加__cmp__。完整列表参考Think like a Computer Scientist的Appendix B。