인스턴스 간에 클래스 데이터가 공유되지 않도록 하려면 어떻게 해야 합니까?
제가 원하는 것은 다음과 같은 행동입니다.
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
'programing' 카테고리의 다른 글
클래스 속성을 만드는 방법? (0) | 2023.06.26 |
---|---|
두 개의 선택 테이블을 결합하여 선택 쿼리에 실제 결과를 표시하는 것과 동일하지 않은 이유 (0) | 2023.06.26 |
Numpy argsort - 그것은 무엇을 하고 있습니까? (0) | 2023.06.26 |
매니페스토.MF: 메인 클래스와 시작 클래스의 차이 (0) | 2023.06.26 |
문자열에서 특정 문자 제거 (0) | 2023.06.26 |