我理解使用属性的主要目的之一是验证和格式化。例如,我有一个如下所示的User类。我希望firstname和lastname在设置时大写。如果我可以编写以下代码来实现相同的格式化结果,为什么还需要属性?
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()
答案 0 :(得分:4)
你是对的,你不需要需要属性来设置属性进行验证,或者在进行属性查找时执行特殊行为。但是属性更易读,写得更好。在您想要动态访问属性的情况下(即,您不知道在类定义时您将拥有哪些属性),我会坚持使用__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
这是如何工作的演示:
>>> user = User('steve', 'martin')
>>> user.firstname
'Steve'
>>> user.firstname = 'dean'
>>> user.firstname
'Dean'
答案 1 :(得分:1)
我会使用它们,因为它们更有意义。并且属性直接列在类下面,而您正在执行的操作列在函数下。这意味着人类可以看到每个对象应该具有的属性,并且计算机也可以:您将属性添加到类定义中,因此它不仅仅是所有用户巧合的东西。
此外,可能使属性的实现变得高效。您在Python中进行名称查找,您拥有的名称越多,您需要的支票就越多。通过更高级别的编程,您可以让解释器决定如何实现属性,而较新的解释器可以使用更智能的技巧来实现。
答案 2 :(得分:1)
关于Python中属性的一个非常酷的观点是,您可以回到过去在应用程序中创建的混乱并修复它而不破坏现有代码。
在Java中,例如,将类变量设置为私有,您可以提供getter和setter函数,并且通常在这些函数中加入一些逻辑,以避免出现荒谬的值。
在Python中,由于类变量默认是公共的,因此很容易创建一种情况,即类的用户会找到各种创造性的输入荒谬值的方法。
当你意识到这一点时,如果你大大改变你的应用程序的逻辑以防止这些荒谬的价值,你可能会创建一个与第一个版本不向后兼容的应用程序的新版本。 这通常会让用户感到非常不满。
属性为您解决此问题:修复混乱,同时保持向后兼容性。
如果您想了解更多有关其工作原理的详细信息,请参阅此页:
'http://www.programiz.com/python-programming/property'
解释得很清楚。