python 装饰器装饰类
@property is a built-in decorator in python language which is used to make functions like getters and setters in a class behave as class properties.
@property是python语言的内置装饰器,用于使类中的诸如getter和setter之类的函数表现为类属性。
To understand the concept in a better way, let's take an example.
为了更好地理解该概念,我们举一个例子。
Below we have a class Student
, which has 3 properties, namely fname
, lname
and fullname
, where fullname is a concatenation of the first two properties.
下面我们有一个Student
类,它具有3个属性,即fname
, lname
和fullname
,其中fullname是前两个属性的串联。
And we have a function too, the email()
function to generate an email address for the student using its first and last names.
我们也有一个函数, email()
函数使用名字和姓氏为学生生成电子邮件地址。
class Student:
def __init__(self, fname, lname):
self.fname = fname
self.lname = lname
self.fullname = self.fname +' '+ self.lname
# generate email using first and last name
def email(self):
return '{}.{}@studytonight.com'.format(self.fname, self.lname)
Let's now create a few objects and call the function email()
and doing so try a few things,
现在,我们创建一些对象并调用函数email()
然后尝试一些操作,
# student s1
s1 = Student('Tony', 'Stark')
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
# now updating the s1 object's first name
s1.first = 'Steve'
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
Fullname of s1 is Tony Stark And email address = [email protected] Fullname of s1 is Tony Stark And email address = [email protected]
s1的全名是Tony Stark并且电子邮件地址= [受电子邮件保护] s1的全名是Tony Stark并且电子邮件地址= [受电子邮件保护]
Now referring to the above code, in class Student
, fname(first name) and lname(last name) are the simple attributes(which are not derived from any other attributes) while fullname and email()
are the derived attributes.
现在参考上面的代码,在Student
类中, fname (名字)和lname (姓氏)是简单属性(它们不是从任何其他属性派生的),而fullname和email()
是派生的属性。
Here fullname is declared as a variable and email
is declared as a function.
在这里, 全名被声明为变量, email
被声明为函数。
Now coming to the output, we can see that for a student when the first name is changed then email gets changed automatically but the fullname doesn't change because email()
is a function which is called at the time when we want the email to be returned while fullname
is set at the time of initialisation of the object.
现在转到输出,我们可以看到,对于一个学生,当名字更改后,电子邮件会自动更改,但是全名不会更改,因为email()
是一个函数,当我们希望电子邮件被调用时在初始化对象时设置fullname
返回。
If you want to fix the problem for fullname, it can be done by making a function similar to email to get fullname as well. But, this will result in the overhead of changing all the access made to fullname in all the python files which have used the Student
class.
如果您想解决全名问题,可以通过制作类似于电子邮件的函数来获取全名来解决。 但是,这将导致将所有使用Student
类的python文件中对全名的所有访问权限更改为全名的开销。
Also, creating a function is not the pythonic way of solving this problem. But then what is?
同样,创建函数也不是解决此问题的有效方法。 但是那是什么呢?
使用@property
装饰器 (Using @property
Decorator)
Now we will use the @property
in the above program to solve the problem of fullname(which we saw above) by creating a getter function for fullname which will allow it to be used as a simple variable and will always return the updated value of fullname property.
现在,我们将在上述程序中使用@property
来解决全名的问题(如上所示),方法是为全名创建一个getter函数,该函数将其用作简单变量,并将始终返回全名的更新值属性。
Let's see how we can do so,
让我们看看如何做到这一点,
class Student:
def __init__(self, fname, lname):
self.fname = fname
self.lname = lname
@property
def fullname(self):
return self.fname +' '+ self.lname
# generate email using first and last name
def email(self):
return '{}.{}@studytonight.com'.format(self.fname, self.lname)
s1 = Student('Tony', 'Stark')
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
# now updating the s1 object's first name
s1.first = 'Steve'
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
Output:-
输出:-
Fullname of s1 is Tony Stark And email address = [email protected] Fullname of s1 is Steve Stark And email address = [email protected]
s1的全名是Tony Stark并且电子邮件地址= [受电子邮件保护] s1的全名是Steve Stark并且电子邮件地址= [受电子邮件保护]
In the above example, @property
decorator is used on the function named as fullname()
. Now, this function will work as a fullname attribute and also can work as a getter because of the @property
decorator attached to it.
在上面的示例中,在名为fullname()
的函数上使用了@property
装饰器。 现在,由于该函数附加了@property
装饰器,因此它可以用作全名属性,也可以用作吸气剂。
使用@property
Decorator定义setter
和deleter
方法 (Defining setter
and deleter
methods with @property
Decorator)
Similar to the getter method(we have defined in the previous example) we can also define setter and deleter methods for any attribute which is using @property
in Python.
类似于getter方法(在上一个示例中已定义),我们还可以为在Python中使用@property
任何属性定义setter和deleter方法。
The setter method will set the value of the attribute and the deleter method will delete the attribute from the memory.
setter方法将设置属性的值,而deleter方法将从内存中删除属性。
Let's implement a setter and deleter method for our fullname attribute. For defining a setter and deleter method, for an attribute with @property
decorator set on its getter method, we use a special syntax, where we put @ATTRIBUTE_NAME.setter
and @ATTRIBUTE_NAME.deleter
decorator on function with name same as the ATTRIBUTE_NAME. This is shown in the below example,
让我们为fullname属性实现一个setter和Deleter方法。 为了定义设置器和删除器方法,对于在其getter方法上设置了@property
装饰器的属性,我们使用一种特殊的语法,在该函数中,将@ATTRIBUTE_NAME.setter
和@ATTRIBUTE_NAME.deleter
装饰器放置在名称与ATTRIBUTE_NAME相同的函数上。 在下面的示例中显示,
class Student:
def __init__(self, fname, lname):
self.fname = fname
self.lname = lname
@property
def fullname(self):
return self.fname +' '+ self.lname
#setter for the fullname
@fullname.setter
def fullname(self, name):
# split the name from space
fname, lname = name.split(" ")
self.first = fname
self.last = lname
#deleter for fullname
@fullname.deleter
def fullname(self):
self.first = None
self.last = None
print('Deleted the fullname')
# generate email using first and last name
def email(self):
return '{}.{}@studytonight.com'.format(self.fname, self.lname)
s1 = Student('Tony', 'Stark')
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
# now updating the s1 object's first name
s1.first = 'Steve'
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
#setting new value of fullname
s1.fullname = 'Berry Banner'
print('New Fullname of s1 is ', s1.fullname)
#deleting the fullname
del s1.fullname
Fullname of s1 is Tony Stark And email address = [email protected] Fullname of s1 is Steve Stark And email address = [email protected] New fullname of s1 is Berry Banner Deleted the fullname.
s1的全名是Tony Stark并且电子邮件地址= [受电子邮件保护] s1的全名是Steve Stark且电子邮件地址= [email受保护] s1的新全名是Berry Banner删除了全名。
In the above example, we have successfully created getter, setter and deleter using the @property
decorator.
在上面的示例中,我们已经使用@property
装饰器成功创建了getter , setter和deleter 。
The simple syntax for creating setter and deleter is:
创建setter和deleter的简单语法是:
@attribute_name.(setter/getter/deleter)
@attribute_name.(setter/getter/deleter)
property()
函数 (The property()
function)
Instead of using @property
decorator, we can use the property()
function in python to create getters, setters and deleters in python.
除了使用@property
装饰器,我们还可以在python中使用property()
函数在python中创建getter,setter和Deleters。
Syntax: property(fget, fset, fdel, doc)
语法: property(fget, fset, fdel, doc)
Where the parameters means:
参数含义:
fget()
: used to get the value of attribute
fget()
:用于获取属性的值
fset()
: used to set the value of atrribute
fset()
:用于设置atrribute的值
fdel()
: used to delete the attribute value
fdel()
:用于删除属性值
doc()
: string that contains the documentation (docstring) for the attribute
doc()
:包含属性文档(文档字符串)的字符串
return: It returns a property attribute from the given getter, setter and deleter.
return :它从给定的getter,setter和deleter返回属性属性。
Below, is an example showing the use of the property()
function for the same Student
class with the same functions defined as getter, setter and deleter.
下面是一个示例,该示例显示了对具有相同功能(定义为getter,setter和deleter的同一Student
类property()
的property()
函数的用法。
class Student:
def __init__(self, fname, lname):
self.fname = fname
self.lname = lname
self.fullname = fname+' '+lname
def fullname_getter(self):
return self.fname +' '+ self.lname
def fullname_setter(self,name):
firstname, lastname = name.split()
self.fname = firstname
self.lname = lastname
def fullname_deleter(self):
self.fname = None
self.lname = None
print('Deleted the fullname.')
def email(self):
return '{}.{}@email.com'.format(self.fname, self.lname)
fullname = property()
fullname = fullname.getter(fullname_getter)
fullname = fullname.setter(fullname_setter)
fullname = fullname.deleter(fullname_deleter)
# this can be done in a single line too
# fullname = property(fullname_getter, fullname_setter, fullname_deleter)
s1 = Student('Tony', 'Stark')
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
# now updating the s1 object's first name
s1.first = 'Steve'
print('Fullname of s1 is ', s1.fullname)
print('And email address = ', s1.email())
#setting new value of fullname
s1.fullname = 'Berry Banner'
print('New Fullname of s1 is ', s1.fullname)
#deleting the fullname
del s1.fullname
Fullname of s1 is Tony Stark And email address = [email protected] Fullname of s1 is Steve Stark And email address = [email protected] New fullname of s1 is Berry Banner Deleted the fullname.
s1的全名是Tony Stark并且电子邮件地址= [受电子邮件保护] s1的全名是Steve Stark且电子邮件地址= [email受保护] s1的新全名是Berry Banner删除了全名。
In this example, either we can use property()
function and specify all the getter, setter and deleter functions as parameters in one go using the syntax described above or in multiple code lines.
在此示例中,我们可以使用property()
函数并使用上述语法或在多行代码中一次性指定所有getter,setter和deleter函数作为参数。
python 装饰器装饰类