夏天到,装饰器让Python秀出性感属性:Property+Decorators+-+Getters,+Setters,+and+Deleters

John Smith曾经是我的好基友,没有之一,今天我们拿他做个试验:
初始代码,我们做一个打印员工John Smith信息的类,实例emp_1会用类属性输出:

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
        self.email = first + "." + last + '@email.com'
    def fullname(self):
        return '{} {}'.format(self.first, self.last)
    
emp_1 = Employee('John', 'Smith')

print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname())
John
John.Smith@email.com
John Smith

下面,当我们在类外修改了实例emp_1的属性,那么实例属性输出也改变;不过,你会发现问题,员工的first name和last name被改变了,但是,email却没有自动跟着改变。

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
        self.email = first + "." + last + '@email.com'
    def fullname(self):
        return '{} {}'.format(self.first, self.last)
    
emp_1 = Employee('John', 'Smith')

#New edit
emp_1.first = 'Jim' 

print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname())
Jim
John.Smith@email.com
Jim Smith

Anyway,我还是想让email自动改变,在Python中该怎么办呢?
我们可以定义一个函数输出;不过你会发现,你需要一个讨厌的括号才能像刚才一样去调出email。

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
#         self.email = first + "." + last + '@email.com'
    def email(self):
        return '{}.{}@email.com'.format(self.first, self.last)

    def fullname(self):
        return '{} {}'.format(self.first, self.last)
    
emp_1 = Employee('John', 'Smith')

#New edit
emp_1.first = 'Jim' 

print(emp_1.first)
print(emp_1.email())
print(emp_1.fullname())
Jim
Jim.Smith@email.com
Jim Smith

当我们还是想像调用属性一样来调用函数return结果,这时候,一个叫做property的装饰器说它可以解决完美主意者的烦恼;当然,当fullname发现这个技巧时候,它也果断跟进了一个@property,并脱掉了它的括号,因为这样很性感,特别是在一个完美的夏天。

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
#         self.email = first + "." + last + '@email.com'
    @property
    def email(self):
        return '{}.{}@email.com'.format(self.first, self.last)
    @property
    def fullname(self):
        return '{} {}'.format(self.first, self.last)
    
emp_1 = Employee('John', 'Smith')

#New edit
emp_1.first = 'Jim' 

print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
Jim
Jim.Smith@email.com
Jim Smith

于是,John很兴奋,因为其实他想改名很久了,他直接来了个:
emp_1.email = ‘Lady.Gaga@email.com’
emp_1.fullname = ‘Lady GaGa’
可是,结果脱掉外套后的他,摔了一个大跟头:AttributeError: can’t set attribute

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
#         self.email = first + "." + last + '@email.com'
    @property
    def email(self):
        return '{}.{}@email.com'.format(self.first, self.last)
    @property
    def fullname(self):
        return '{} {}'.format(self.first, self.last)
    
emp_1 = Employee('John', 'Smith')

emp_1.email = 'Lady.Gaga@email.com'
emp_1.fullname = 'Lady GaGa'

print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-43-05f72f854431> in <module>()
     13 emp_1 = Employee('John', 'Smith')
     14 
---> 15 emp_1.email = 'Lady.Gaga@email.com'
     16 emp_1.fullname = 'Lady GaGa'
     17 


AttributeError: can't set attribute

这时候,property说话了,它说:除了帮你脱掉外套,我还可以做更多…

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
    @property
    def email(self):
        return '{}.{}@email.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(' ')
                # fullname的定义方式为emp_1.fullname = 'Lady Gaga',所以split一下
        self.first = first
        self.last = last  
emp_1 = Employee('John', 'Smith')
emp_1.fullname = 'Lady Gaga'

print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
Lady
Lady.Gaga@email.com
Lady Gaga

Jonh问:你为什么不早说?竟然有这种神操作,我不想活了。property说:如此需求,我也可以帮你实现:

class Employee:
    def __init__(self, first, last):
        self.first = first
        self.last = last
    @property
    def email(self):
        return '{}.{}@email.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(' ')
                # fullname的定义方式为emp_1.fullname = 'Lady Gaga',所以split一下
        self.first = first
        self.last = last
    @fullname.deleter
    def fullname(self):
        print("Gandiao Name")
        self.first = None
        self.last = None
    
emp_1 = Employee('John', 'Smith')

emp_1.fullname = 'Lady Gaga'

print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)

print("before deleter")
del emp_1.fullname
print("after deleter")

print(emp_1.first)
print(emp_1.email)
print(emp_1.fullname)
Lady
Lady.Gaga@email.com
Lady Gaga
before deleter
Gandiao Name
after deleter
None
None.None@email.com
None None

Jonh惊呆了,说:你,你竟然删除了我…
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值