programing

인스턴스 간에 클래스 데이터가 공유되지 않도록 하려면 어떻게 해야 합니까?

lastmoon 2023. 6. 26. 21:36
반응형

인스턴스 간에 클래스 데이터가 공유되지 않도록 하려면 어떻게 해야 합니까?

제가 원하는 것은 다음과 같은 행동입니다.

class a:
    list = []

x = a()
y = a()

x.list.append(1)
y.list.append(2)
x.list.append(3)
y.list.append(4)

print(x.list) # prints [1, 3]
print(y.list) # prints [2, 4]

물론, 인쇄할 때 실제로 일어나는 일은 다음과 같습니다.

print(x.list) # prints [1, 2, 3, 4]
print(y.list) # prints [1, 2, 3, 4]

분명히 그들은 수업 시간에 데이터를 공유하고 있습니다.a원하는 행동을 달성하기 위해 어떻게 별도의 인스턴스를 얻을 수 있습니까?

원하는 항목:

class a:
    def __init__(self):
        self.list = []

클래스 선언 내부의 변수를 선언하면 인스턴스 멤버가 아닌 "클래스" 멤버가 됩니다.내부에서 이를 선언합니다.__init__메서드는 개체의 모든 새 인스턴스와 함께 구성원의 새 인스턴스가 생성되는지 확인합니다. 이는 사용자가 찾고 있는 동작입니다.

받아들여진 답변은 효과가 있지만 조금 더 설명을 해줘도 아프지 않습니다.

클래스 특성은 인스턴스를 만들 때 인스턴스 특성이 되지 않습니다.값이 할당되면 인스턴스 특성이 됩니다.

원래 코드에서 값이 할당되지 않았습니다.list인스턴스화 후 속성. 따라서 클래스 속성으로 남아 있습니다.내부 목록 정의__init__효과가 있는 이유는__init__인스턴스화 후 호출됩니다.또는 이 코드는 원하는 출력도 생성합니다.

>>> class a:
    list = []

>>> y = a()
>>> x = a()
>>> x.list = []
>>> y.list = []
>>> x.list.append(1)
>>> y.list.append(2)
>>> x.list.append(3)
>>> y.list.append(4)
>>> print(x.list)
[1, 3]
>>> print(y.list)
[2, 4]

그러나 숫자나 문자열과 같은 불변의 객체는 할당 없이 값을 변경할 수 없기 때문에 질문에서 혼란스러운 시나리오는 결코 발생하지 않습니다.예를 들어 문자열 속성 유형이 있는 원본과 유사한 코드는 문제 없이 작동합니다.

>>> class a:
    string = ''


>>> x = a()
>>> y = a()
>>> x.string += 'x'
>>> y.string += 'y'
>>> x.string
'x'
>>> y.string
'y'

요약하자면 클래스 속성은 인스턴스화 메서드에 있는지 여부에 관계없이 값이 할당된 경우에만 인스턴스 속성이 됩니다.인스턴스화 후 속성에 값을 할당하지 않을 경우 정적 속성을 가질 수 있기 때문에 이 방법이 좋습니다.

수락된 답변이 정확하지만, 저는 약간의 설명을 추가하고 싶습니다.

작은 운동을 해요.

우선 클래스를 다음과 같이 정의합니다.

class A:
    temp = 'Skyharbor'

    def __init__(self, x):
        self.x = x

    def change(self, y):
        self.temp = y

자, 여기 뭐가 있죠?

  • 우리는 속성을 가진 매우 간단한 수업이 있습니다.temp어떤 것이 끈입니까?
  • __init__설정하는 방법self.x
  • 변경 방법 설정self.temp

지금까지 꽤 솔직했죠, 그렇죠?이제 이 수업을 가지고 놀기 시작하겠습니다.먼저 이 클래스를 초기화합니다.

a = A('Tesseract')

이제 다음을 수행합니다.

>>> print(a.temp)
Skyharbor
>>> print(A.temp)
Skyharbor

음.a.temp예상대로 작동했지만 대체 어떻게 한 거죠?A.temp일이요? 글쎄요, 효과가 있었습니다. 왜냐하면 임시직은 계급적 속성이기 때문입니다.파이썬의 모든 것은 객체입니다.는 클래스 A의 .type는 따서는속다음의유속지성다니입는되해에 입니다.A및 temp 을 변경할 값을 변경할 수 .A.).a), 의된 값이 A수업을 시작합니다. 그럼 다음과 같이 하죠.

>>> A.temp = 'Monuments'
>>> print(A.temp)
Monuments
>>> print(a.temp)
Monuments

흥미롭군, 그렇지 않나요?그리고 및 는 여전히 동일하다는 것을 유의하십시오.

Python 으로 "Python"이라는 의 " 객체에는 "Python"이라는 이름이 붙습니다.__dict__특성 목록을 포함하는 특성입니다.된 예제 " 이사전포예아 에 알 겠 보 습 니 대 다 해 개 에 체 함 제 된 습 ▁let 겠 니 다 보 : 알 아 이 대 ▁objects 해 ▁for ▁contains ▁diction

>>> print(A.__dict__)
{
    'change': <function change at 0x7f5e26fee6e0>,
    '__module__': '__main__',
    '__init__': <function __init__ at 0x7f5e26fee668>,
    'temp': 'Monuments',
    '__doc__': None
}
>>> print(a.__dict__)
{x: 'Tesseract'}

:temp은 속이다중나다니됩열에음성▁among에 나열되어 .A클스의속다같과다습니음은성래▁class다'.x이 인스턴스에 대해 나열됩니다.

그럼 어떻게 정의된 값을 얻을 수 있습니까?a.temp 경우.a▁of▁magic다▁well의 마법입니다.__getattribute__()방법. Python에서 은 자동으로 이 파썬에구자를 쓸 때 합니다.a.temp이 Python »을 합니다.a.__getattribute__('temp')이 메서드는 속성 조회 작업을 수행합니다. 즉, 다른 위치를 찾아 속성의 값을 찾습니다.

표준 __getattribute__()먼저 개체의 내부 사전(사전)을 검색한 다음 개체 자체의 유형을 검색합니다.이 경우a.__getattribute__('temp') 번째로 을 실행합니다.a.__dict__['temp']그리고 나서.a.__class__.__dict__['temp']

우리의 자, 이우리를 해 보겠습니다.change방법:

>>> a.change('Intervals')
>>> print(a.temp)
Intervals
>>> print(A.temp)
Monuments

이제 우리가 사용한 것은self,print(a.temp)와는 다른 가치를 제공합니다.print(A.temp).

이제 우리가 비교해보면,id(a.temp)그리고.id(A.temp)그들은 다를 것입니다.

"list" instance "수준 속성" 닌 "등급 속성" 로 "등급 속성" 했 "등급 속성" 습니다선언를가아▁"다니로습"list"했▁"▁property를▁property.의 범위를 하려면 턴스수서자지범속정사의성용 "self".__init__방법(또는 상황에 따라 다른 곳).

에서 인스턴스 속성을 엄격하게 초기화할 필요는 없습니다.__init__방법이지만 그것은 더 쉽게 이해할 수 있게 해줍니다.

그래서 여기에 있는 거의 모든 반응들은 특정한 점을 놓치고 있는 것처럼 보입니다.클래스 변수는 아래 코드에 표시된 것처럼 인스턴스 변수가 되지 않습니다.메타 클래스를 사용하여 클래스 레벨에서 변수 할당을 가로채면 a.myattr이 재할당될 때 클래스의 필드 할당 마법 메서드가 호출되지 않음을 알 수 있습니다.이는 할당이 새 인스턴스 변수를 만들기 때문입니다.이 동작은 클래스 변수가 없지만 필드 할당을 허용하는 두 번째 클래스에서 설명한 클래스 변수와는 전혀 관련이 없습니다.

class mymeta(type):
    def __init__(cls, name, bases, d):
        pass

    def __setattr__(cls, attr, value):
        print("setting " + attr)
        super(mymeta, cls).__setattr__(attr, value)

class myclass(object):
    __metaclass__ = mymeta
    myattr = []

a = myclass()
a.myattr = []           #NOTHING IS PRINTED
myclass.myattr = [5]    #change is printed here
b = myclass()
print(b.myattr)         #pass through lookup on the base class

class expando(object):
    pass

a = expando()
a.random = 5            #no class variable required
print(a.random)         #but it still works

IN SHORT 클래스 변수는 인스턴스(instance) 변수와 아무런 관련이 없습니다.

명확하게 말하자면, 그들은 단지 사례를 조사할 수 있는 범위 안에 있을 뿐입니다.클래스 변수는 실제로 클래스 개체 자체의 인스턴스 변수입니다.메타 클래스 자체도 개체이므로 원하는 경우 메타 클래스 변수를 가질 수도 있습니다.다른 개체를 만드는 데 사용하든 그렇지 않든 모든 것은 개체이므로 단어 클래스의 다른 언어 사용 시맨틱에 얽매이지 마십시오.파이썬에서 클래스는 실제로 다른 객체를 만드는 방법과 그들의 동작을 결정하는 데 사용되는 객체일 뿐입니다.메타 클래스는 이 점을 자세히 설명하기 위해 클래스를 만드는 클래스입니다.

예, 목록이 클래스 속성이 아닌 객체 속성이 되도록 하려면 "생성자"에서 선언해야 합니다.

다른 인스턴스에서 공유하는 변수를 보호하려면 인스턴스를 만들 때마다 새 인스턴스 변수를 만들어야 합니다.클래스 내부의 변수를 선언하는 경우 클래스 변수이며 모든 인스턴스에서 공유됩니다.예를 들어, 인스턴스를 참조하여 init 메서드를 사용하여 변수를 다시 초기화해야 합니다.

Python Objects Class by Programiz에서.com:

__init__()됩니다.이 특수 함수는 해당 클래스의 새 개체가 인스턴스화될 때마다 호출됩니다.

이러한 유형의 함수를 OOP(Object Oriented Programming)의 생성자라고도 합니다.일반적으로 모든 변수를 초기화하는 데 사용합니다.

예:

class example:
    list=[] #This is class variable shared by all instance
    def __init__(self):
        self.list = [] #This is instance variable referred to specific instance

언급URL : https://stackoverflow.com/questions/1680528/how-to-avoid-having-class-data-shared-among-instances

반응형