这个属性装饰器(python)有啥问题[重复]
Posted
技术标签:
【中文标题】这个属性装饰器(python)有啥问题[重复]【英文标题】:what is wrong with this property decorator (python) [duplicate]这个属性装饰器(python)有什么问题[重复] 【发布时间】:2020-09-28 19:59:57 【问题描述】:我尝试将属性装饰器添加到我的班级,但出了点问题。
我有 6 个错误!!!
我的代码:
class person:
def __init__ (self, name, age):
self.name = name
self.age = age
@property
def age(self):
return self.age
@age.setter
def age(self, new_age):
if isinstance(new_age, int):
self.age = new_age
def __str__ (self):
return f"self.name is self.age"
p1 = person('moe',34)
print(person)
【问题讨论】:
您能否更具体地了解什么错误?您可以编辑您的问题以包含他们的堆栈跟踪吗? 您在最后一行打印person
(类),而不是p1
(类实例)
尝试使用唯一的名称 - 目前您的属性 def age() 和 self.age 是相同的名称。将一个更改为不同的 - 研究文档:docs.python.org/3/library/functions.html#property
是的,谢谢大家的解释。我忘了在打印函数中添加 p1 而不是 person lol 除了同名错误
【参考方案1】:
您使用相同的名称,然后该属性会隐藏该成员。这使得这些递归问题成为self.age
在setter
中一次又一次地调用自身。
您需要使用不同的属性名称,如下所示:
class person:
def __init__ (self, name, age):
self.name = name
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, new_age):
if isinstance(new_age, int):
self._age = new_age
def __str__ (self):
return f"self.name is self.age"
p1 = person('moe',34)
print(p1)
【讨论】:
是的,我确实遇到了递归错误。我不太明白你的解释。它是如何从二传手那里来的???为什么要更改属性的名称 在你的setter
中看到你有self.age = new_age
,这条线将再次调用setter
,这将一次又一次地进行,直到达到最大递归。您必须使用其他名称。还有一件事,你不能有相同的 r 方法和类成员的名称。询问您是否还有任何困惑
谢谢我明白你的意思,但是“属性影响成员”是什么意思
这意味着如果属性名称是age
并且成员名称是age
那么无论何时使用classname.age
都意味着您正在访问该属性。例如有一个方法input()
,如果你有一个名为input
的变量,它会隐藏内置的input()
,你将无法使用它,试一试你就会明白
感谢您抽出宝贵时间将我的问题标记为已回答:)【参考方案2】:
您将age
定义为类方法和类变量。当您引用self.age
时,解释器无法知道您的意思。
把代码改成这个来修复它:
class person:
def __init__ (self, name, age):
self.name = name
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, new_age):
if isinstance(new_age, int):
self._age = new_age
def __str__ (self):
# Here you can either use the property or the real variable
return f"self.name is self.age"
p1 = person('moe',34)
print(person)
【讨论】:
【参考方案3】:您的代码中可能有两个错误。
-
首先,方法和属性不能同名
age
。
如果我正确理解您的意图,您应该打印实例 p1
。
类似这样的:
class person:
def __init__ (self, name, age):
self.name = name
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, new_age):
if isinstance(new_age, int):
self._age = new_age
def __str__ (self):
return f"self.name is self._age"
p1 = person('moe',34)
print(p1)
你得到:
moe is 34
【讨论】:
谢谢我理解,但我不认为更改变量的名称可以实现任何目标 哦,nvm,我刚刚注意到我打印的人大声笑以上是关于这个属性装饰器(python)有啥问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章