魔法方法 (magic method) 的方法名前后被双下划线 (dunder) 所包围,构造函数 init 就是最常见的魔法方法。
其实所有类都是 object 类的子类,而 object 类里有两个重要的魔法方法,repr 和 str,任何 object 的子类都会继承这两个方法。 如果 Employee 中实现了 str,那么 print() 函数打印出来的是 str 方法里的内容。 如果 Employee 中没实现 str 但实现了 repr,那么 print() 函数打印出来的是 __repr__方法里的内容。 那么为了让 Employee 对象的打印出来信息更有用或者可读性更强,我们需要用心实现 repr 和 str 这两种方法。 repr ()方法 该方法是给开发者用的,因此输出应该是准确而无歧义的。我们希望能打印出来的字符串就能直接用于构建 Employee 对象。 str()方法 该方法是给用户用的,因此输出应该是可读性强的。该方法是给用户用的,因此输出应该是可读性强的。
class Employee: raise_rate=2.99 num_of_emps=0 def __init__(self,first,last,pay): self.first=first self.last=last self.pay=pay self.email=first+'.'+last+'@gmail.com' def fullname(self): return '{},{}'.format(self.first,self.last) def apply_raise(self): self.pay= int(self.pay*self.raise_rate) def __repr__(self): return 'Employee(\'{}\',\'{}\',{})'.format(self.first,self.last,self.pay) def __str__(self): return '{}-{}'.format(self.fullname(),self.email) emp_1 = Employee( 'Steven', 'Wang', 200000 ) print( emp_1.__repr__() ) print( emp_1.__str__()) #Employee('Steven','Wang',200000) #Steven,Wang-Steven.Wang@gmail.com魔法方法 add 重载了二元运算符 +
class Employee: raise_rate=2.99 num_of_emps=0 def __init__(self,first,last,pay): self.first=first self.last=last self.pay=pay self.email=first+'.'+last+'@gmail.com' def fullname(self): return '{},{}'.format(self.first,self.last) def apply_raise(self): self.pay= int(self.pay*self.raise_rate) def __repr__(self): return 'Employee(\'{}\',\'{}\',{})'.format(self.first,self.last,self.pay) def __str__(self): return '{}-{}'.format(self.fullname(),self.email) def __add__(self,other): return self.pay+other.pay emp_1 = Employee( 'Steven', 'Wang', 200000 ) emp_2 = Employee( 'Sen', 'yang', 300000 ) print( emp_1+emp_2 )#500000属性装饰器 改变属性,举个例子 如果把 Steven Wang 的名改成 Tracy,也没问题,除了邮箱地址中的名还是 Steven。这是怎么回事呢?
class Employee: raise_rate=2.99 num_of_emps=0 def __init__(self,first,last,pay): self.first=first self.last=last self.pay=pay self.email=first+'.'+last+'@gmail.com' def fullname(self): return '{},{}'.format(self.first,self.last) emp_1 = Employee( 'Steven', 'Wang', 200000 ) print(emp_1.first) print(emp_1.email) print(emp_1.fullname()) emp_1.first='Tracy' print(emp_1.first) print(emp_1.email) print(emp_1.fullname())原因就是 email 已经在构建 emp_1 是就已经定好了,即在运行 init 方法时就已经定好了。而 fullname() 里面的 self.first 和 self.last 每次都可以获取更新后的 first 和 last。 用巧方法解决呗
class Employee: raise_rate=2.99 num_of_emps=0 def __init__(self,first,last,pay): self.first=first self.last=last self.pay=pay @property def email(self): return '{}.{}@gmail.com'.format(self.first,self.last) @property def fullname(self): return '{},{}'.format(self.first,self.last) emp_1 = Employee( 'Steven', 'Wang', 200000 ) print(emp_1.first) print(emp_1.email) print(emp_1.fullname) emp_1.first='Tracy' print(emp_1.first) print(emp_1.email) print(emp_1.fullname)现在如果突发奇想改全名 (fullname),把 Steven Wang 改成 Tracy Mcgrady。结果报错,因为改全名会同时影响名 (first) 和姓 (last)。 这时我们需要用装饰器来定义 setter 方法,语法为 @fullname.setter。实现逻辑很简单,讲全名分拆成名和姓,然后再赋值给 self.first 和 self.last。
class Employee: raise_rate=2.99 num_of_emps=0 def __init__(self,first,last,pay): self.first=first self.last=last self.pay=pay @property def email(self): return '{}.{}@gmail.com'.format(self.first,self.last) @property def fullname(self): return '{},{}'.format(self.first,self.last) @fullname.setter def fullname(self,name): first,last=name.split(' ') self.first=first self.last=last emp_1 = Employee( 'Steven', 'Wang', 200000 ) print(emp_1.first) print(emp_1.email) print(emp_1.fullname) emp_1.fullname='Tracy Mcgrady' print(emp_1.first) print(emp_1.email) print(emp_1.fullname)同样的方法删去
class Employee: raise_rate=2.99 num_of_emps=0 def __init__(self,first,last,pay): self.first=first self.last=last self.pay=pay @property def email(self): return '{}.{}@gmail.com'.format(self.first,self.last) @property def fullname(self): return '{},{}'.format(self.first,self.last) @fullname.setter def fullname(self,name): first,last=name.split(' ') self.first=first self.last=last @fullname.deleter def fullname(self): print('Delete Name:',self.fullname) self.first=None self.last=None emp_1 = Employee( 'Steven', 'Wang', 200000 ) print(emp_1.fullname) del emp_1.fullname print(emp_1.fullname)输出结果: