簡體   English   中英

通常在python中從Base創建Derived類

[英]Universally create Derived class from Base in python

在SO上發現了一些問題,但仍然沒有答案......有一個數據類

class Proxy(object):
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

有一個getter類應該從不同的源讀取這些數據

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 []

我需要一個具有更多選項的Proxy類

class SecureProxy(Proxy):
    def __init__(self, ip, port):
        super(SecureProxy, self).__init__(ip, port)
        self.transparent = None

現在我想改進FileProxyGetter,如下所示:

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

那么如何在Python中普遍地從基類中轉換或創建派生類的實例 如果不需要對類進行更改會更好。

或者你能建議更多的pythonic方式來發展這種關系和架構嗎?

您可以使用繼承:

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)

但在這種情況下使用合成可能更有用。

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")

編輯:python中的一個臟技巧,用於切換對象的類型:

>>> 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

兩個不同類型的對象共享相同狀態的另一個臟技巧:

>>> 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'

然而,這些技巧,雖然可能在Python中,我不會稱它們為pythonic,也不是一個好的OO設計。

Python 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM