programing

데이터 클래스의 클래스 특성 선언에서 기본값을 변경할 수 없는 이유는 무엇입니까?

powerit 2023. 5. 28. 21:06
반응형

데이터 클래스의 클래스 특성 선언에서 기본값을 변경할 수 없는 이유는 무엇입니까?

이것은 이전에 질문을 받았을 가능성이 높은 것처럼 보이지만, 한 시간 정도의 검색은 결과를 얻지 못했습니다.데이터 클래스에 기본 목록 인수를 전달하는 은 유망해 보였지만, 제가 찾고 있는 것은 아닙니다.

문제는 다음과 같습니다. 클래스 속성에 변수 값을 할당하려고 하면 오류가 발생합니다.

@dataclass
class Foo:
    bar: list = []

# ValueError: mutable default <class 'list'> for field a is not allowed: use default_factory

대신 다음을 사용해야 한다는 오류 메시지를 수집했습니다.

@dataclass
class Foo:
    bar: list = field(default_factory=list)

그런데 왜 변경 가능한 기본값이 허용되지 않습니까?가변 기본 인수 문제의 회피를 강제하기 위한 것입니까?

제 질문은 문서에서 상당히 명확하게 답변된 것 같습니다(shme가 언급한 것처럼 PEP 557에서 파생됨).

Python은 클래스 속성에 기본 멤버 변수 값을 저장합니다.데이터 클래스를 사용하지 않고 다음 예를 고려하십시오.

class C:
    x = []
    def add(self, element):
        self.x.append(element)

o1 = C()
o2 = C()
o1.add(1)
o2.add(2)
assert o1.x == [1, 2]
assert o1.x is o2.x

클래스의 두 인스턴스는C동일한 클래스 변수를 공유합니다.x역시

데이터 클래스 사용(이 코드가 유효한 경우)

@dataclass
class D:
    x: List = []
    def add(self, element):
        self.x += element

다음과 유사한 코드를 생성합니다.

class D:
    x = []
    def __init__(self, x=x):
        self.x = x
    def add(self, element):
        self.x += element

클래스를 사용하는 원래 예제와 동일한 문제가 있습니다.C즉, 클래스의 두 인스턴스.D다음에 대한 값을 지정하지 않음x클래스 인스턴스를 만드는 경우 동일한 복사본을 공유합니다.x데이터 클래스는 일반적인 Python 클래스 만들기만 사용하기 때문에 이 동작도 공유합니다.데이터 클래스에서 이 상태를 탐지하는 일반적인 방법은 없습니다.대신, 데이터 클래스는 다음을 발생시킵니다.ValueError유형의 기본 매개 변수를 탐지하는 경우list,dict또는set이것은 부분적인 해결책이지만 많은 일반적인 오류로부터 보호합니다.

위의 답변은 정확하지 않습니다.빈 목록과 같은 변수 기본값은 다음을 사용하여 데이터 클래스에 정의할 수 있습니다.default_factory.

    @dataclass
    class D:
        x: list = field(default_factory=list) 

기본 팩토리 함수를 사용하면 필드의 기본값으로 >mutable 유형의 새 인스턴스를 만들 수 있습니다.

   @dataclass
   class D:
       x: list = field(default_factory=list)

   assert D().x is not D().x

링크는 여기에 있습니다.

가져오기 필드(예: 데이터 클래스).

from dataclasses import dataclass, field

목록에 사용할 수 있습니다.

@dataclass
class Foo:
    bar: list = field(default_factory=list)

default_factory에서 호출 가능한 파일을 사용하면 됩니다.

from dataclasses import dataclass, field

@dataclass
class SomeClass:
    """
    """

    some_list: list = field(default_factory=lambda: ["your_values"])

모든 인스턴스가 동일한 목록을 변환하도록 하려면 다음을 수행합니다.

from dataclasses import dataclass, field

SHARED_LIST = ["your_values"]
    
@dataclass
class SomeClass:
    """
    """
    
    some_list: list = field(default_factory=lambda: SHARED_LIST)

언급URL : https://stackoverflow.com/questions/53632152/why-cant-dataclasses-have-mutable-defaults-in-their-class-attributes-declaratio

반응형