我知道使用属性的主要目的之一是用于验证和格式化。例如,我有一个如下所示的 User 类。我希望名字和姓氏在设置时大写。如果我可以编写以下代码来实现相同的格式化结果,为什么还需要属性?
class User:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
def __setattr__(self, attr, value):
if attr == 'firstname':
self.__dict__[attr] = value.capitalize()
elif attr == 'lastname':
self.__dict__[attr] = value.capitalize()
Run Code Online (Sandbox Code Playgroud)
你说得对,你不需要来对设置属性执行验证,或者在进行属性查找时执行特殊行为。但属性更具可读性且更易于编写。在您想要动态访问属性的情况下(也就是说,您不知道在类定义时将拥有哪些属性),我会坚持使用__getattr__和。__setattr__否则,请使用属性,因为它们是一个非常容易识别的 Python 习惯用法。
事实上,在这种情况下,如果您有两个执行相同验证的属性,我可能会使用描述符:
class NameDescriptor(object):
def __init__(self, key):
self.key = key
def __get__(self, obj, objtype):
return getattr(obj, self.key)
def __set__(self, obj, val):
setattr(obj, self.key, val.capitalize())
class User(object):
firstname = NameDescriptor('_firstname')
lastname = NameDescriptor('_lastname')
def __init__(self, first, last):
self.firstname = first
self.lastname = last
Run Code Online (Sandbox Code Playgroud)
其工作原理的演示:
>>> user = User('steve', 'martin')
>>> user.firstname
'Steve'
>>> user.firstname = 'dean'
>>> user.firstname
'Dean'
Run Code Online (Sandbox Code Playgroud)