默認情況下,Python 似乎將類成員視為 ClassVar。雖然來自檔案:https : //docs.python.org/3/library/dataclasses.html#class-variables
dataclass() 實際檢查欄位型別的兩個地方之一是確定欄位是否是 PEP 526 中定義的類變數。它通過檢查欄位的型別是否為 Typing.ClassVar 來實作。如果欄位是 ClassVar,則將其作為欄位排除在外,并被資料類機制忽略。模塊級 fields() 函式不會回傳此類 ClassVar 偽欄位。
問題的最小再現:
from dataclasses import dataclass
import numpy as np
@dataclass
class Color:
r: int = 0
g: int = 0
b: int = 0
@dataclass
class NumberColor:
color: Color = Color()
number: int = 0
alpha = np.zeros(3)
x = NumberColor()
y = NumberColor()
print("Id of x:", id(x))
print("Id of y:", id(y))
print('-----------')
print("Id of x.color:", id(x.color))
print("Id of y.color:", id(y.color))
print('-----------')
print("Id of x.number:", id(x.number))
print("Id of y.number:", id(y.number))
print('-----------')
print("Id of x.alpha:", id(x.alpha))
print("Id of y.alpha:", id(y.alpha))
print('-----------')
x.color.r = 255
x.number = 10
print(x.__dict__)
print(y.__dict__)
產量:
Id of x: 140660354709392
Id of y: 140660357249008
-----------
Id of x.color: 140660355994096
Id of y.color: 140660355994096
-----------
Id of x.number: 9788960
Id of y.number: 9788960
-----------
Id of x.alpha: 140660289932624
Id of y.alpha: 140660289932624
-----------
{'color': Color(r=255, g=0, b=0), 'number': 10}
{'color': Color(r=255, g=0, b=0), 'number': 0}
uj5u.com熱心網友回復:
不,color您的NumberColor類的屬性不被視為類變數。相反,它__init__是dataclass裝飾器為您的類創建的方法的共享默認引數。
它與可變默認引數的任何其他問題沒有太大不同:
def foo(c = Color()): # default value is created here
return c
x = foo() # get the default value
print(x.r) # 0, as is expected
x.r = 255
y = foo() # get the default again
print(y.r) # 255, not 0 as you might naively expect
在您的代碼中,與xand等價的y是x.colorandy.color屬性。
為避免此問題,您可以將一個dataclasses.field物件分配給類主體中的名稱,并使用該類的default_factory引數Color(您還需要對用作默認值的 numpy 陣列執行類似操作alpha):
from dataclasses import dataclass, field
@dataclass
class NumberColor:
color: Color = field(default_factory=Color) # use a field!
number: int = 0
alpha = field(default_factory=lambda: np.zeros(3)) # here too
沒有必要使用fieldfor number(或 for 中的屬性Color),因為int物件是不可變的,并且您不應該關心是否將相同的物件用于任何給定的0值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/347559.html
標籤:Python
下一篇:PythonTypeError:“SeriesGroupBy”和“SeriesGroupBy”的實體之間不支持“>”
