java形式的get,set
class Employee(object):
def __init__(self, name):
self._name = name
def get_name(self):
return self._name
def set_name(self, name):
self._name = name
pythonic的get,set
但在python中,如果有get,set,应该直接使用属性,这样做简单快捷
class PEmployee(object):
def __init__(self, name):
self.name = name
set中修改值
有时候需要在set中,修改和判断设置的值是否符合要求,这时候在python中需要用到@property修饰符
class SubPEmployee(PEmployee):
def __init__(self, name):
super(SubPEmployee,self).__init__(name)
self._id = 0
@property
def id(self):
return self._id
@id.setter
def id(self, pid):
if pid == 0 :#希望设置的id不为0
raise ValueError(u'id不能设置为0')
self._id = pid +1
这时候直接使用id赋值为0就会抛出异常ValueError
spemployee = SubPEmployee(u'好')
spemployee.id = 0
子类不修改父类属性
class APEmployee(PEmployee):
@property
def name(self):
return self._name
@name.setter
def name(self, name):
if hasattr(self, '_name'):
raise AttributeError(u"不能给父类中的name赋值")
self._name = name
这时直接给父类中的属性赋值是不可以的,抛出AttributeError
aemployee = APEmployee('test')
aemployee.name = 'tester'
复杂的逻辑注意
在set中不要有其他属性的操作,也不要有复杂的操作,如果有其他属性的操作会受到其他属性的干扰,而复杂的操作会比较耗时,这不利于类对象的创建
属性干扰
class PPEmploy(object):
def __init__(self, salary):
self._salary = salary
self.money = 0.0
@property
def salary(self):
return self._salary
@salary.setter
def salary(self, salary):
self.money+=salary
self._salary = salary
当salary属性改变时,money属性也随之发生了变化,这样做很难管制money属性,
应该避免这种情况
pemployee = PPEmploy(1000.0)
pemployee.salary = 2000.0
print pemployee.salary
print pemployee.money #money属性也同时改变了,这样容易造成困惑
复杂操作
如果每次执行一下赋值都会执行很多代码,一个是时间上消耗较多,另外就是偏离了给赋值操作的职责,不如直接把代码抽取出来
@salary.setter
def salary(self, salary):
self.money+=salary
print '*'*20
print u'这里有100行代码来判断这个属性以及和它赋值'
print '*'*20
self._salary = salary
下面的做法更明确
def __init__(self,salary) :
self.salary = salary
def process_salary(self):
print '*'*20
print u'这里有100行代码来处理salary这个属性'
print '*'*20
参考书籍:effective python