【问题标题】:About python class __init__ and Decorators关于 python 类 __init__ 和装饰器
【发布时间】:2023-03-14 05:16:02
【问题描述】:

当我学习python的“属性”时,令我惊讶的是,输出与预期的不一样。代码如下所示:

class HideX(object):
    def __init__(self,x):
        self.x = x
    def get_x(self):
        return ~self.__x
    def set_x(self,x):
        assert isinstance(x,int),\
        '"x" must be an integer!'
        self.__x = ~x
    x = property(get_x, set_x)


    inst = HideX(20)
    #inst.x = 20#

当它执行inst = HideX(20)时。我认为它会调用__init__(self,x),因此将执行指令self.x = x。出现问题。我认为它不会调用x = property(get_x, set_x),因为self.x 在类的主体中(它在类的顶部)。我一直认为 只有在课外(如#..#所示)我们才能访问x = property(get_x, set_x)我错了吗?你能明白我的意思吗?

解决了: 经过反复测试,我惊奇地发现,当我们执行inst = HideX(20)时,代码x = property(get_x, set_x) 将首先被调用,而不是'init(self,x)'。完全出乎我的意料!!!(在java中,当我们创建一个实例时,init()我想我会先调用类,也许我错了)

(1)你能解释一下内在机制吗?我是新手,感谢您的耐心等待。

下面的代码是我复制的段:

class HideXX(object):
    def __init__(self, x):
        self.x = x

    @property
    def x():
        def fget(self):
            return ~self.__x

        def fset(self,x):
            assert isinstance(x,int),\
            '"x" must be an integer!'
            self.__x = ~x

        return locals()

    #x = property(**x())
inst =  HideXX(1)

但无法正常运行 错误代码是:

File "<string>", line 21, in <module>
File "<string>", line 4, in __init__
AttributeError: can't set attribute

(2)书错了吗??当我删除 @property 并添加代码 'x = property(**x())' 它有效!!!

你能给我解释一下原因吗?非常感谢

【问题讨论】:

    标签: python properties decorator init


    【解决方案1】:

    对于您的第一个问题,答案很简单,x 是类的属性(不是类的对象/实例),它将在定义类时(而不是创建对象时)进行评估。

    一个例子来说明这一点 -

    >>> class CA:
    ...     y = print("Hello")
    ...     def __init__(self):
    ...             print("Blah")
    ...
    Hello
    >>> c = CA()
    Blah
    

    正如您所见,y 的值是在定义类时计算的,与类中的所有函数相同,它们在定义类时定义,但仅在调用函数时才计算.

    此外,使用 @property 与 property(**x()) 不同,当您使用后者时,**x() 解析为 -

    {'fget': <function HideXX.x.<locals>.fget at 0x00943B28>, 'fset': <function HideXX.x.<locals>.fset at 0x00943CD8>}
    

    然后这些位置参数用于设置属性xgettersetter,而@property 注释用于定义属性x 的getter。

    【讨论】:

    • 感谢您的耐心等待。 Yr的第一个答案对我很有帮助,第二个答案也很清楚。但是上面的示例(@property def x():...)是从名为 Core ‘Python Programming,2nd Edition’ 的书中复制而来的。书错了吗?还是我做错了什么?
    • 你得到错误的例子?是直接从书上抄来的吗?
    • 是的,我从 复制关于第 422 页的网络中有 pdf [code.google.com/p/ownerpress/source/browse/trunk/startZine/…
    • 是的,我认为这本书有点错误,在第二种情况下,由于我们使用decorators而不是静态类变量,我们将不得不做HideXX.x = 10或设置@987654333 @ 到某个任意数字,然后我们才能为其创建实例。
    • 另外,如果您认为某个答案已经令人满意地回答了您的问题,请记住接受它们(点击答案左侧的勾号)。这将对社区有所帮助。
    猜你喜欢
    • 2014-02-16
    • 2011-06-30
    • 2014-01-01
    • 1970-01-01
    • 2011-03-23
    • 2011-04-28
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    相关资源
    最近更新 更多