为什么我们需要在Python中使用属性?

5

我理解使用属性的主要目的之一是进行验证和格式化。例如,我有一个如下所示的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()

由于属性看起来更紧凑,而且没有字段名称的重复。 - Andrey
2
如果 x.a = b and x.a != b,那么这实际上不是一个很好的编程实践。 - Andrey
3个回答

4
你说得没错,确实不需要在设置属性时执行验证或执行特殊行为时使用属性,但是属性更易读且更好写。我建议在需要动态访问属性(即在类定义时不知道将拥有哪些属性)的情况下使用__getattr__和__setattr__。否则,请使用Properties,因为它们是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'

3
Python中关于属性的一个非常酷的点是,您可以回到过去创建的应用程序中进行修复,而不会破坏现有的代码。
例如,在Java中,将类变量设置为私有后,需要提供getter和setter函数,并通常在这些函数中放置一些逻辑以避免荒谬的值。
在Python中,由于类变量默认为公共变量,因此很容易创建一种情况,即您的类的用户会发现各种创造性的方式来输入荒谬的值。
当您意识到这一点时,如果您大幅改变您的应用程序逻辑以防止这些荒谬的值,那么您可能会创建一个与第一个版本不兼容的新版本应用程序。这通常会让用户非常不满意。
属性为您提供了一种解决方法:修复混乱,同时保持向后兼容性。
如果您想了解更多详细信息,请访问此页面:

'http://www.programiz.com/python-programming/property'

解释得很好。


1
我会使用它们,因为它们更有意义。属性直接列在类下面,而您正在做的是列在函数下面。这意味着人类可以看到每个对象应该具有哪些属性,计算机也可以:您正在将属性添加到类定义中,因此不仅仅是所有用户都巧合拥有的东西。
另外,属性的实现是有效的。可能您在Python中进行名称查找,并且您拥有的名称越多,需要的检查就越多。通过在更高的级别上编程,您让解释器决定如何实现属性,而新的解释器可以使用更智能的技巧来实现属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接