简体   繁体   中英

Is there really a bug in using python dataclass and property together?

I have been here:

and could not find a direct answer to why this simple code works fine...

class Vehicle:
    
    def __init__(self, wheels: int = 10):
        self.wheels = wheels # -> calls the setter method
    
    @property
    def wheels(self) -> int:
        print("getting wheels")
        return self._wheels
    
    @wheels.setter
    def wheels(self, wheels: int):
        print("setting wheels to", wheels)
        self._wheels = wheels

v = Vehicle() 
number = v.wheels # -> calls the getter method
print(number)

# last output: 10

...but this one does not (using dataclass ):

from dataclasses import dataclass

@dataclass
class Vehicle:
    
    wheels: int = 10
    
    @property
    def wheels(self) -> int:
        print("getting wheels")
        return self._wheels
    
    @wheels.setter
    def wheels(self, wheels: int):
        print("setting wheels to", wheels)
        self._wheels = wheels

v = Vehicle() 
number = v.wheels
print(number)

# output: <property object at 0x000002042D70DDB0>

even when the official documentation of dataclass tells explicitly in the beginning that the decorator @dataclass adds exactly the __init__ method from the first code, ie, this code:

@dataclass
class Vehicle:
    wheels: int = 10

should add this __init__ :

def __init__(self, wheels: int = 10):
    self.wheels = wheels

Is that really a bug?


Short Note:

The private attribute _wheels is accessed only inside the property 's methods, as it should be (to isolate it).

I found in others threads (listed above) that this attribute is manipulated outside the methods, exposed as 'public', which is not desired in some cases.

That's a bug in your code.

This code:

wheels: int = 10

sets wheels to 10 , then this code immediately after:

@property
def wheels(self) -> int:
    print("getting wheels")
    return self._wheels

sets wheels to a property instance.

@dataclass can't see the 10 . Your 10 is gone. The annotation remains, so @dataclass creates a wheels field, but your field's default value is a property instance, not 10 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM