这个属性装饰器(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.agesetter 中一次又一次地调用自身。 您需要使用不同的属性名称,如下所示:

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)有啥问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python 装饰器和装饰器模式有啥区别?

有啥方法可以获取具有装饰器、Python、Django 的视图名称列表

“@”装饰器(在 Python 中)[重复]

在 Python 中使用属性的删除器装饰器

python装饰器参数[重复]

Python 装饰器:在测试前运行装饰器