3

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

我需要一个具有更多选项的代理类,例如

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方式来开发这种关系和架构吗?

4

1 回答 1

4

您可以使用继承:

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
于 2013-05-25T14:30:30.100 回答