为什么 python property() 函数分配给类变量而不是实例变量?

发布于 2025-01-12 11:44:37 字数 1077 浏览 0 评论 0原文

我正在学习 python 中的封装和抽象,并且遇到了属性函数和装饰器。常见的例子是这样的。

class Celsius():
    def __init__(self, temperature = 0):
        self.set_temperature(temperature)

    def to_fahrenheit(self):
        return (self._temperature * 1.8) + 32

    def get_temperature(self):
        print("Getting value")
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

    temperature = property(get_temperature,set_temperature)

我不明白为什么属性函数将描述符分配给 Temperature 而不是 self.Temperature。难道不是应该为实例而不是类创建 getter 或 setter 功能吗?

诸如

self.temperature = property(get_temperature,set_temperature)

using 之

test = Celsius()
pprint(test.__dict__)

类的东西会返回实例对象仅具有 self._Temperature 属性(我们试图将其设为私有)。 使用 pprint(Celsius.__dict__) 返回的实际上是具有我们在使用对象时访问的温度属性的类,据我所知,这没有意义,因为我对创建功能感兴趣到实例并访问实例属性,而不是类属性。

提前致谢 :)

I'm learning about encapsulation and abstraction in python and i came across the property function and decorator. The common example is something like this.

class Celsius():
    def __init__(self, temperature = 0):
        self.set_temperature(temperature)

    def to_fahrenheit(self):
        return (self._temperature * 1.8) + 32

    def get_temperature(self):
        print("Getting value")
        return self._temperature

    def set_temperature(self, value):
        if value < -273:
            raise ValueError("Temperature below -273 is not possible")
        print("Setting value")
        self._temperature = value

    temperature = property(get_temperature,set_temperature)

I dont understand why the property function is assigning the descriptor to temperature and not self.temperature. Isn't it suppouse to create a getter or setter functionality to a Instance, not to the class?

something like

self.temperature = property(get_temperature,set_temperature)

using

test = Celsius()
pprint(test.__dict__)

returns that the instance object just have the self._temperature attribute (Which we are trying to make private).
using pprint(Celsius.__dict__) returns that is actually the class that have the temperature attribute that we are accessing when using the objects, which to my understanding doesn't make sense since i am interested in creating functionality to the instance and access the instance atributes, not the class attributes.

Thanks in advance :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨夜星沙 2025-01-19 11:44:37

方法之外没有 self。这是定义一个类属性。

@Barmar 上面有一个有用的评论。

常用的类函数参数selfcls在类函数之外不可用。在本例中,您正在定义类的静态成员。默认情况下,以这种方式定义的变量(如您的 Temperature =)是该类的静态成员。

请参阅此处有关静态成员的一些有用提示:Python 中是否可以使用静态类变量?

但是为什么语法是这样的。是不是应该将属性分配给实例变量?

请注意以下事项。 class_static_var = 4 的行为类似于人们查看 cls.class_static_var = 4 的方式,但它与 self.instance_var = 4 不同>。要定义实例变量,可以使用 __init__ 方法

class DemoClass:
    def __init__(self): 
        self.instance_var = 3
    class_static_var = 4

There's no self outside the method. This is defining a class attribute.

@Barmar has a helpful comment above.

The commonly used class function parameters self and cls are not available outside of class functions. In this case, you are defining a static member of the class. It is implied by default that vars (like your temperature =) defined this way are static members of the class.

See some useful tips on static members here: Are static class variables possible in Python?

But why is the syntax like that. Isnt should be assigning the property to a instance variable?

Note the below. The behavior of class_static_var = 4 is similar to how someone may view cls.class_static_var = 4, however it is not similar to self.instance_var = 4. To define a instance var, you can use the __init__ method

class DemoClass:
    def __init__(self): 
        self.instance_var = 3
    class_static_var = 4
血之狂魔 2025-01-19 11:44:37

您没有解释为什么您认为描述符必须位于实例命名空间中,而是查看文档

描述符就是我们所说的任何定义__get__()的对象,
__set__()__delete__()。 ...描述符仅在用作时才有效
类变量。当放入实例中时,它们没有任何效果。

因此,要使属性发挥作用,它必须是类的成员,而不是实例

如果您有一个描述符、Descriptor 和一个 Foo 类:

class Foo:
    bar = Descriptor()

foo = Foo()

那么描述符协议将在或者 上调用

Foo.bar

,或者

foo.bar

在任何情况下,这是一件好事。不需要每个实例都携带对描述符的引用。就像方法一样,它属于,但实例可以访问它。

You don't explain why you believe the descriptor has to be in the instance namespace, but looking at the documentation:

A descriptor is what we call any object that defines __get__(),
__set__(), or __delete__(). ... Descriptors only work when used as
class variables. When put in instances, they have no effect.

So, for property to work at all, it must be a member of the class, not the instance.

If you have a descriptor, Descriptor, and a class Foo:

class Foo:
    bar = Descriptor()

foo = Foo()

then the descriptor protocol will be invoked on either

Foo.bar

or

foo.bar

In any case, this is a good thing. There's no need for each instance to carry around a reference to the descriptor. Just like a method, it will belong to the class but instances have access to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文