__init__.py
__future__
中,以便旧的代码能在旧版本中测试新特性。# python2中/是整除,python3中//是整除,/是除法但得到浮点数
>>> from __future__ import division
>>> print 10 / 3
3.3333333333333335
class Person(object):
pass
def cmp(x,y):
if x < y :
return -1
elif x > y :
return 1
else :
return 0
p1 = Person()
p1.name = 'Bart' # 可以直接给实例添加属性,不同实例的属性可以不同
p2 = Person()
p2.name = 'Adam'
p3 = Person()
p3.name = 'Lisa'
L1 = [p1, p2, p3]
L2 = sorted(L1,key=lambda x:x.name)
print L2[0].name
print L2[1].name
print L2[2].name
__init__()
方法,当创建实例时,init()方法被自动调用.__init__()
方法的第一个参数必须是 self(也可以用别的名字,但建议使用习惯用法),后续参数则可以自由指定,和定义函数没有任何区别。 class Person(object):
def __init__(self,name,gender,birth,**kw):
self.name = name
self.gender = gender
self.birth = birth
for k , v in kw.iteritems():
setattr(self,k,v)
xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student')
print xiaoming.name
print xiaoming.job
Python对属性权限的控制是通过属性名来实现的,如果一个属性由双下划线开头__
,该属性就无法被外部访问
如果一个属性以__xxx__
的形式定义,那它又可以被外部访问了,以__xxx__
定义的属性在Python的类中被称为特殊属性,有很多预定义的特殊属性可以使用
类属性
class Person(object):
address = 'Earth'
def __init__(self, name):
self.name = name
class Person(object):
count = 0
def __init__(self,name):
Person.count += 1
self.name = name
p1 = Person('Bob')
print(Person.count)
p2 = Person('Alice')
print(Person.count)
p3 = Person('Tim')
print(Person.count)
class Person(object):
address = 'Earth'
def __init__(self, name):
self.name = name
p1 = Person('Bob')
p2 = Person('Alice')
print 'Person.address = ' + Person.address
p1.address = 'China' # 试图在实例变量中修改类属性
print 'p1.address = ' + p1.address
print 'Person.address = ' + Person.address
print 'p2.address = ' + p2.address
输出:
Person.address = Earth
p1.address = China # Ⅰ
Person.address = Earth
p2.address = Earth # Ⅱ
Python中方法也是属性
types.MethodType()
把一个函数变为一个方法: # 给一个实例动态添加方法并不常见,直接在class中定义要更直观。
import types
def fn_get_grade(self):
if self.score >= 80:
return 'A'
if self.score >= 60:
return 'B'
return 'C'
class Person(object):
def __init__(self, name, score):
self.name = name
self.score = score
p1 = Person('Bob', 90)
p1.get_grade = types.MethodType(fn_get_grade, p1, Person)
print p1.get_grade()
# => A
p2 = Person('Alice', 65)
print p2.get_grade()
# ERROR: AttributeError: 'Person' object has no attribute 'get_grade'
# 因为p2实例并没有绑定get_grade
# get_grade:是函数而不是方法(直接把 lambda 函数赋值给 self.get_grade 和绑定方法有所不同,函数调用不需要传入 self,但是方法调用需要传入 self)
class Person(object):
def __init__(self, name, score):
self.name = name
self.score = score
self.get_grade = lambda: 'A'
p1 = Person('Bob', 90)
print p1.get_grade
print p1.get_grade()
Python中的类方法
@classmethod
class Person(object):
__count = 0 # 私有属性
# 通过标记一个 @classmethod,该方法将绑定到 Person 类上,而非类的实例。类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.__count 实际上相当于 Person.__count。
@classmethod
def how_many(cls):
return cls.__count
def __init__(self,name):
self.name = name
Person.__count += 1
print Person.how_many()
p1 = Person('Bob')
print Person.how_many()
# 因为是在类上调用,而非实例上调用,因此类方法无法获得任何实例变量,只能获得类的引用(Person.how_many)。