2013-07-26 2 views
3

파이썬 객체를 어디서나 다른 객체로 대체하려면 어떻게해야합니까?파이썬 객체 하나 하나를 다른 곳으로 대체하십시오

나는 두 개의 클래스 인 SimpleObjectFancyObject을 가지고 있습니다. 나는 SimpleObject을 만들었으며 그것에 대해 여러 가지 언급을했습니다. 이제 FancyObject을 만들고 모든 참조가 새 객체를 가리 키도록하고 싶습니다.

a = SimpleObject() 
some_list.append(a) 
b = FancyObject() 

a = b는 그냥 어떤 지점으로 변경, 내가 원하는 것이 아니다. 나는 다음과 같이 작동하지만 읽지 않습니다. 나는이 해키이지만, 어떤 방법이 알고

*a = *b 

:

a.__dict__ = b.__dict__ 

는 내가 원하는 것은 (의사-C)에 해당합니다 : 나는 오류가 "쓸 수 없습니다 __dict__ 속성"GET 이것을 성취하기 위해서?

+0

그래서, 당신은'A'가 저장되는 장소에 저장되는 데이터를 변경하려면? 나는 점심 식사 후 대답을 게시 할 것이다. – pradyunsg

+0

@ Schoolboy 예. 기본적으로 저는 간단한 객체를 넣었습니다. 필요가 생길 때 좀 더 복잡한 객체로 그것을 (게으르게) 승격시키고 싶습니다. a와 b는 같은 인터페이스를 가지고 있으므로이를 사용하는 코드가이를 처리 할 수 ​​있어야합니다. – jdm

답변

0

방법이 없습니다. 그것은 당신이 불변의 객체를 돌연변이시키고 모든 종류의 끔찍한 짓을하게 할 것입니다.

x = 1 
y = (x,) 
z = {x: 3} 
magic_replace(x, [1]) 
# x is now a list! 
# The contents of y have changed, and z now has an unhashable key. 

x = 1 + 1 
# Is x 2, or [1, 1], or something stranger? 
+0

글쎄,'y','z'의 내용은'x'가 이전에 언급했던 것을 참조하기 때문에 바뀌지 않을 것입니다. 변경된 유일한 것은'x'가 말하는 것입니다. (내가 틀렸다면 나는 C를 모른다. – pradyunsg

+1

'x'가 무엇을 가리키는 지 바꾸고 싶다면,'x = whatever'이 당신이하는 것입니다. 마술처럼 바꾸고 싶다면'x'는 새로운 객체를 가리키고 있습니다. 이것은 오래된 객체를 사용하는 모든 곳에서 볼 수 있어야합니다 (예 : dicts와 tuples). – user2357112

+0

@ Schoolboy 그러나 그것은 OP가 요구 한 것입니다 : 'x'뿐만 아니라 동일한 객체를 참조하는 다른 모든 이름을 대체하는 것입니다. 당신이 깨닫지 못했을 경우, 파이썬'1'은 객체이고, 메인 파이썬 구현에서 값 '1'을 사용하는 모든 것은 단순히 같은 객체를 참조하는 것입니다. – Duncan

1

개체를 별도 모듈의 글로벌 네임 스페이스에 넣을 수 있으며 필요하면 원숭이가 패치 할 수 있습니다.

objstore.py :

replaceable = object() 

sample.py :

import objstore 

b = object() 

def isB(): 
    return objstore.replaceable is b 

if __name__ == '__main__': 
    print isB()#False 
    objstore.replaceable = b 
    print isB()#True 

P.S. 원숭이 패치를 의지하는 것은 나쁜 디자인의 증상입니다.

1

방금 ​​this을 발견했습니다. 그것의 replace_all_refs 함수는 꽤 잘 작동하는 것 같다.

+2

링크 할 내용에 대해 소식에 조금 더 많은 정보를 포함해야합니다. – Michelle

0

당신은 여러 옵션이 있습니다 외관 패턴을 사용하여, 처음부터이의

  1. 디자인, 또는 단일 가변 용기 ((즉, 기본 코드의 모든 개체는 뭔가 다른 프록시입니다) 즉 모든 변수는 목록을 보유하고 있으며 그러한 참조를 통해 목록의 내용을 변경할 수 있습니다. 장점은 언어의 실행 기계와 함께 작동하며 영향을받는 코드에서 비교적 쉽게 발견 할 수 있다는 것입니다. 단점 : 더 많은 코드.
  2. 항상 동일한 단일 변수를 참조하십시오. 이것은 위의 구현 중 하나입니다. 깨끗하고 멋진 코드는 아닙니다. 나는 이것을 멀리 추천 할 것이다.
  3. debug, gc 및 introspection 기능을 사용하여 기준에 맞는 모든 객체를 검색하고 실행 중에 변수를 변경하십시오. 단점은 코드 실행 중에 변수의 값이 변경되어 영향을받는 코드에서 검색 할 수 없다는 것입니다. 변경이 원자 단위 (오류 클래스 제거) 일지라도 값이 다른 유형으로 판별 된 코드 실행 후 변수의 유형을 변경할 수 있으므로 해당 코드에서 합리적으로 예상 할 수없는 오류가 발생합니다.예

    a = iter(b) # will blow up if not iterable 
    [x for x in b] # before change, was iterable, but between two lines, b was changed to an int. 
    

더 세세하게 들어, 문자열 및 문자열이 아닌 서열을 구별 할 때 (문자열 형성 기능들을 반복하여도 반복 가능한 자체 된 문자열을 산출하는 것이 있기 때문에) 구조를 평탄화 할 때 코드가 손상되었을 수 있습니다.

또 다른 대답은 옵션 3을 구현하는 pyjack에 대해 언급합니다. 작동 할 수도 있지만 언급 된 모든 문제가 있습니다. 디버깅 및 개발에만 적합합니다.

0

목록과 같은 변경 가능한 개체를 활용하십시오.

이 작동
a = [SimpleObject()] 
some_list.append(a) 
b = FancyObject() 
a[0] = b 

증명 :

class SimpleObject(): 
    def Who(self): 
     print 'SimpleObject' 

class FancyObject(): 
    def Who(self): 
     print 'FancyObject' 

>>> a = [SimpleObject()] 
>>> a[0].Who() 
SimpleObject 
>>> some_list = [] 
>>> some_list.append(a) 
>>> some_list[0][0].Who() 
SimpleObject 
>>> b = FancyObject() 
>>> b.Who() 
FancyObject 
>>> a[0] = b 
>>> some_list[0][0].Who() 
FancyObject 
관련 문제