滥用 'property' 保留字

Misuse of 'property' reserved word

所以我有一些使用保留字 property 的遗留代码,嗯,错了。在继承的基础class中,他们基本上已经实现了。

class TestClass(object):

    def __init__(self, property):
        self._property = property

    @property
    def property(self):
        return self._property


test = TestClass('test property')
print(test.property)

运行没有错误。如果你在下面添加另一个方法,你会得到,

class TestClass2(object):

    def __init__(self, property):
        self._property = property

    @property
    def property(self):
        return self._property

    @property
    def other_property(self):
        return 'test other property'


test = TestClass2('test property')
print(test.property)
print(test.other_property)

抛出:

---> 10     @property
     11     def other_property(self):
     12         print('test other property')

TypeError: 'property' object is not callable

因为你知道你已经覆盖了本地命名空间中的property

class TestClass3(object):

    def __init__(self, property):
        self._property = property

    @property
    def other_property(self):
        return 'test other property'

    @property
    def property(self):
        return self._property


test = TestClass3('test property')
print(test.property)
print(test.other_property)

如果您始终在 class 的底部定义 property 覆盖,则可以解决此问题。如果 property 方法仅定义在基础 class 上,那么您继承的东西也可以解决,因为命名空间。

class TestClass4(TestClass):

    def __init__(self, property):
        super(TestClass4, self).__init__(property)

    @property
    def other_property(self):
        return 'test other property'


test = TestClass4('test property')
print(test.property)
print(test.other_property)

我义愤填膺地说我们必须在大量遗留代码中更新这个变量名,因为 GAAAAH,但除了必须记住在 property 定义的定义之上添加新方法之外很少修改了基础 class,这实际上并没有破坏任何东西,对吗?

不要隐藏内置函数... 几乎不进行任何重构,您就可以避免完全隐藏内置函数

使用 __getattr__ 而不是 @property 来 return 您的 _property 会员...

class TestClass(object):
    def __init__(self):
        self._property = 12

    def __getattr__(self,item):
        if item == "property": 
           #do your original getter code for `property` here ... 
           # now you have not overwritten the property keyword at all
           return getattr(self,"_property") # just return the variable
class TestClass2(TestClass):
    def __init__(self):
        self._property = 67

print TestClass2().property

class MySubClass(TestClass):
    @property
    def a_property(self):
        return 5

print MySubClass().property
print MySubClass().a_property

真的,顺便说一句,恕我直言,没有任何理由在 python 中使用 @property。它所做的只是在以后让其他程序员感到困惑,并掩盖了你实际上是在调用一个函数的事实。我以前经常这样做……我现在避免这样做,除非我有非常非常令人信服的理由不这样做

您可以随时将 property 重新映射到另一个名称。只要您选择的名称与您的其他 class 属性不匹配,它就不会暴露在 class 的外部接口中,所以您命名什么并不重要它。

tproperty = property

class Test(...)

    @tproperty
    def property(self):
        ....

是的,如果您 总是property 方法的定义之上添加新方法,则不会出现任何问题。因此,请在代码中对此效果做一个很好的大注释。希望任何想要在派生 class 中覆盖 property 的人会先查看基础 class 并查看您的评论...

顺便说一句,__init__ 方法的 property arg 也隐藏了 property,但我想这不是问题。

理想情况下,应该有人清理这个烂摊子,但我知道这样做可能不划算。

另外,我有点困惑为什么最初的编码器首先将 property 设为 @属性。只有在必须动态计算属性值时才应使用该构造,而不是简单地返回静态属性。也许他们是 Python 的新手,他们被告知这是在 Python...

中做吸气剂的方法