Home > Blockchain >  Why python property() function is assigned to a class variable and not an instance variable?
Why python property() function is assigned to a class variable and not an instance variable?

Time:03-08

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 :)

CodePudding user response:

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

CodePudding user response:

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.

  • Related