滥用 '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...
中做吸气剂的方法
所以我有一些使用保留字 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...