面向对象的python属性修饰符

面向对象的python属性修饰符,python,decorator,Python,Decorator,我正在测试在OOP中使用@property的想法: class Person(object): @property def name(self): return self.name @name.setter def name(self, newname): self.name = newname james = Person() james.name = 'James Bond' print(james.name) >&g

我正在测试在OOP中使用
@property
的想法:

class Person(object):
    @property
    def name(self):
        return self.name

    @name.setter
    def name(self, newname):
        self.name = newname

james = Person()
james.name = 'James Bond'
print(james.name)
>>> RecursionError: maximum recursion depth exceeded
不知怎的,这给了我一个递归错误


但是如果我将
self.name
更改为
self.\u name
,似乎可以解决问题。因此,当我使用
name()
作为
@property
时,我想我无法设置
self.name

错误的原因是您试图返回一个与
属性所修饰的方法名称完全相同的属性。因此,当您调用方法
name
时,调用会再次触发该方法,因为
self.name
是类中声明的方法。这将触发非终止递归。而是更改属性名称:

class Person(object):
   @property
   def name(self):
     return self._name

   @name.setter
   def name(self, newname):
      self._name = newname

此外,如果您认为u表示法很难看,那么可以创建内部代理对象(例如python 3.3+):


因此,我发现的方法,即添加
,是一种正确的方法?@code\u Control\u jxie0755在这种情况下,您只需更改变量名。通常,
\u variablename
用于大多数
属性的演示中。另一种方法是使用
self.\u dict.\u['name']
,这有点神秘,但却是隐藏属性值的一种非常酷的方式。描述符协议的全部要点是
obj.x
调用
x.。\uuuu get\uuuu
。你并没有真正消除
\uuu
的主要缺点,您可以创建另一个属性供用户修改。也许类装饰器的小魔术可以保护变量不被重写:但不能防止字段访问和操作。我认为我们需要像
inspect
这样的东西来做。正如我为另一个答案所建议的那样,
self.\uu dict\uuuu['name']
通过利用类上的数据属性优先于实例dict条目来隐藏属性。但是如果我写
s.\uu dict\uuu['name']=“foo”
我可以写
s.name=“bar”
之后。鉴于许多关键变量通常在类构造函数中定义/分配。。。
import types

class Person(object):
   def __init__(self):
       self.me = types.SimpleNamespace(name = "")

   @property
   def name(self):
     return self.me.name

   @name.setter
   def name(self, newname):
      self.me.name = newname