2013-05-25 2 views
1

가 SO에 대한 몇 가지 질문을 찾았지만 여전히 아무 대답이 없다 파이썬에서 자료에서 파생 클래스를 생성 소스 보편적으로 다양한에서 이러한 데이터를 읽을 생각하는 게터 클래스가있다</p> <pre><code>class Proxy(object): def __init__(self, ip, port): self.ip = ip self.port = port </code></pre> <p>데이터 클래스가있다 ...

class FileProxyGetter(ProxyGetter): 
    def __init__(self, fname = "d:\\proxies.txt"): 
     self.fileName = fname 

    def Get(self): 
     proxies = [] 

     f = open(self.fileName) 

     for l in f.xreadlines(): 
      proxies.append(Proxy.fromstring(l[:-1])) 

     f.close() 

     return proxies 

    def Update(self): 
     return [] 

나는 지금 내가 원하는
class SecureProxy(Proxy): 
    def __init__(self, ip, port): 
     super(SecureProxy, self).__init__(ip, port) 
     self.transparent = None 

같은 더 많은 옵션과 프록시 클래스가 필요
class FileSecureProxyGetter(FileProxyGetter): 
    def Get(self): 
     proxies = super(FileProxyGetter, self).Get() 
     secureProxies = [] 
     for proxy in proxies: 
      # Create or Cast Proxy to SecureProxy. 
      # The transparent should be initialized to None or any other value that I may need 
      secureProxies.append(SecureProxy(proxy)) 

     return secureProxies 

그래서 방법은 내가 캐스트 않거나 보편적으로 파이썬에서 기본 클래스에서 파생 된 클래스의 인스턴스를 생성 다음과 같이 FileProxyGetter을 향상시킬 수 있습니다. 필요한 클래스를 변경하지 않는 것이 좋습니다.

그런 관계와 아키텍처를 개발하는 더 많은 비유를 제안 할 수 있습니까??

class FileProxyGetter(ProxyGetter): 
    ... 
    def MakeProxy(self, *args, **kwargs): 
     return Proxy.fromstring(*args, **kwargs) 
    def Get(self): 
     ... 
      proxies.append(self.MakeProxy(l[:-1])) 
     ... 
    ... 
class FileSecureProxyGetter(FileProxyGetter): 
    def MakeProxy(self, *args, **kwargs): 
     return SecureProxy.fromstring(*args, **kwargs) 

을하지만 구성을 사용하려면이 경우에는 아마 더 유용 :

+1

내가 요점을 파악하지 말아 - 당신은'Proxy'와'FileProxyGetter' 있습니다. 그런 다음'SecureProxy'라고 쓰면'FileSecureProxyGetter'가 자동으로 나타나기를 원합니다 - 맞습니까? –

+0

@GillBates 아니, 나는 그것을 수동으로 만들었다. 내가 ProxyProxyProxyProxyProxyProxyProxy를 호출하여 SecureProxy를 생성하려고합니다. – Romeno

+2

문제가 해결되지는 않지만 파일 행을 읽는 방법에는 두 가지 문제가 있습니다. 첫째, 파일을 열고 자동으로 닫으려면'with with open (..) as f :'를 사용하십시오. 예외가 있거나 조기에 복귀하더라도 작동합니다. 그런 다음'for line in f : '는 파일 행을 반복하는 관용적 인 방법입니다. 즉, 문제를 해결하기 위해 공장에서 파생 된 모든 클래스를 등록하는 메타 클래스를 사용 해본 적이 있습니까? 또는 올바른 유형을'ProxyGetter.Get()'에 전달할 수 있습니다. –

답변

2

당신은 상속을 사용할 수 있습니다.

class FileProxyGetter(ProxyGetter): 
    def __init__(self, proxyclass, fname = "d:\\proxies.txt"): 
     self.proxyClass = proxyclass 
     self.fileName = fname 
    ... 
    def Get(self): 
     ... 
      proxies.append(self.proxyclass.fromstring(l[:-1])) 
     ... 
    ... 

# use this as such 
FileProxyGetter(Proxy, "proxies.txt") 
FileProxyGetter(SecureProxy, "secure_proxies.txt") 

EDIT :

>>> class B(object): 
...  def rename(self, name): 
...   self.name = name 
... 
>>> class A(object): 
...  def say(self): 
...   print 'Hello', self.name 
... 
>>> a, b = A(), B() 
>>> a.__dict__ = b.__dict__ 
>>> b.rename('john') 
>>> a.say() 
Hello john 
>>> a.rename('mary') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'A' object has no attribute 'rename' 
>>> b.say() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'B' object has no attribute 'say' 
:

>>> class A(object): 
...  def foo(self): 
...   print 'hello A' 
... 
>>> class B(object): 
...  def foo(self): 
...   print 'hello B' 
... 
>>> a = A() 
>>> a.foo() 
hello A 
>>> a.__class__ 
<class '__main__.A'> 
>>> a.__class__ = B 
>>> a.foo() 
hello B 

다른 유형의 두 개체에 대한 다른 더러운 트릭 동일한 상태를 공유 : 파이썬 더러운 트릭 오브젝트의 타입을 전환 할

그러나이 트릭은 파이썬에서 가능하지만 파이썬 적이거나 훌륭한 OO 디자인이라고 부르지는 않습니다.

일반 기능을 사용하는 대신에 "언 바운드 방법"을 제거했다 최대 파이썬 3.x 및, 또 다른 가능성 :

>>> class A(object): 
...  def say(self): 
...   print('Hello', self.name) 
... 
>>> class B(object): 
...  def rename(self, name): 
...   self.name = name + name 
... 
>>> a = A() 
>>> B.rename(a, 'josh') 
>>> a.say() 
Hello joshjosh 
+0

첫 번째는 훌륭하지만이 솔루션에서는 기본 클래스가 좋지 않습니다. 프록시 클래스의 "종류"가 있는지 알아야합니다. 사실 기본 인스턴스를 가지고있을 때 base로부터 derrived를 만들고 싶습니다. – Romeno

+0

@Romeno : python에서는 변수가 타입이없고, 객체는 강하게 입력됩니다. 객체의 클래스를 전환하는 몇 가지 더러운 트릭이 있습니다. 내 대답을 편집하십시오. –

+0

고마워요. 파이썬에는 이러한 내장 기능이 없다는 것을 분명히합니다. 왜냐하면 그 트릭을 사용해도 __init__이 호출되지 않고 그 방법으로 사용할 수 있다는 것을 염두에두고 클래스를 디자인해야하기 때문입니다. – Romeno