2012-05-24 6 views
1

나는 모든 유형/클래스를 팩토리 메소드로 대체하고 클래스 객체의 대부분의 기능을 유지할 수있는 프록시 클래스를 고안했습니다. 완전히 원래의 클래스 객체를 대체하고 여전히 다음과 같은 것들을 할 수 있기 때문에 내가 팩토리 메소드의 구현을 좋아python에서 repr()과 같은 함수를 내 프록시 클래스와 함께 사용하려면 어떻게해야합니까?

class ProxyClass: 
    def __init__(self, cls): 
     self._ProxyClass_cls = cls 
    def __getattr__(self, name): 
     return getattr(self._ProxyClass_cls, name) 

class _strProxy(ProxyClass): 
    def __call__(self, s): 
     if '\n' in s: 
      raise ValueError 
     if s not in self._cache: 
      self._cache[s] = self._ProxyClass_cls(s) 
     return self._cache[s] 

str = _strProxy(str) 
str._cache = {} 


>>> s = str('hello') 
>>> s 
'hello' 
>>> type(s) 
<type 'str'> 
>>> str('hello\n') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in __call__ 
ValueError 

:

>>> map(str.split, [str('foo bar'), str('bar foo')]) 
[['foo', 'bar'], ['bar', 'foo']] 

유일한 문제 I를 여기 그것이 작동하는 방법의 예입니다 이 예에서

>>> repr(str) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: descriptor '__repr__' of 'str' object needs an argument 

repr() 0을 호출하려고 : 발견 자체는 repr() 같은 클래스의 작업을 함께 type.__repr__(str) 대신입니다. 나는 str.__class__을 변경 수정 시도했지만 문제는이 경우에 불가능하다는 것을 발견 :

>>> str.__class__ = type 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: __class__ must be set to a class 

사람은 repr(str)의 기능이나 내가 뭐하는 거지 달성하기 어쩌면 다른 방법을 복원 할 수있는 방법을 알고 있나요?

파이썬 3.x의에서
class ProxyClass(object): 

당신이 필요가 없습니다, 모든 클래스는, 어쨌든 object에서 상속 :

+0

텍스트 파일에 복사/붙여 넣기를 수행 할 수있는 실제 작업 코드를 게시하는 것이 가장 좋습니다. 위의 내용은 편집해야하는'>>>'와'...'가 있으며, 위의 내용은 추가 내용을 편집 한 후에도 올바르게 작동하지 않는 오타가 있습니다. – steveha

+0

@steveha 좋아, 편집 할게. 오타가 무엇입니까? – Matt

+0

오타를 수정했습니다. '_strProxy()'클래스는'_strPproxy()'를 사용했습니다. (호출은'_strProxy()') – steveha

답변

0

의 모든 클래스가 object에서 상속 있는지 확인 할 이것을하기 위해. 그러나 Python 2.x에서 상속 항목은 올바르게 작동하지 않습니다. 관련된 모든 클래스가 object을 상속하는 "새로운 스타일의 클래스"가 아니면.

repr(str) 위의 변경을 수행 한 후에 문제가되지 않습니다.

+0

이것은 Jakob의 답변과 같은 효과가 있습니다. 원래'str'의'__repr__' (또는'object'의 메소드들)에 접근 할 수 없습니다. – Matt

+0

@Matt,이 질문은 'str'이라는 이름을 래핑 된 클래스로 바인딩하는 것을 보여줍니다. 나는 그것을하지 않을 것이다, 나 자신; 나는 새로운 이름으로 새로운 수업을 만들 것이다. 그러나 나는 오늘 피곤합니다. 그리고 나는 풀 - 온 교사 모드가 아닌 질문에 대답했습니다. 'str'을 리 바인드했다하더라도, 원래 내장 된'str'의'__repr __()'메소드에 접근하는 방법이 있습니다 :'type ('') .__ repr __ (s) – steveha

+0

리바 인딩을하지 않겠습니다. 'str'과 같은 내장 함수를 예제로 사용했습니다. 이것은 내가 정의하고 리바 인딩하려는 (아마 데코레이터로) 아마도 내 자신의 클래스를위한 것입니다. 이것은 팩터 리 함수로 생성자를 오버라이드하고 여전히 클래스로 클래스를 액세스 가능하게 만들 수있는 유일한 방법 인 것 같습니다. – Matt

0

>>> class _strPproxy(ProxyClass): 
...  def __call__(self, s): 
...   self.s = s 
...   if '\n' in s: 
...    raise ValueError 
...   if s not in self._cache: 
...    self._cache[s] = self._ProxyClass_cls(s) 
...   return self._cache[s] 
...  def __repr__(self): 
...   return repr(self.s) 
+0

그 때문에 실제 str .__ repr__에 대한 액세스 권한을 상실했기 때문에 (이 액세스 권한이 필요한지는 확실하지 않지만). – Matt

+0

그럼'str .__ repr__'으로'__original_repr__'을 사용할 수 있습니다 –