python - 在 python 中从 Base 普遍创建派生类

标签 python class architecture derived-class base-class

在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 中通用地从基类转换或创建派生类的实例。如果不需要更改类,那就更好了。

或者你能建议更多Python式的方式来开发这种关系和架构吗?

最佳答案

您可以使用继承:

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 及更高版本中的另一种可能性,它删除了“未绑定(bind)方法”来代替使用常规函数:

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

关于python - 在 python 中从 Base 普遍创建派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16750376/

相关文章:

python - 将 local() 的输出通过管道传输到 Fabric 中远程 run() 命令的标准输入的最佳方法?

Python - 通过字典进行类型转换循环

java - 使用线程池和 BlockingQueue 重新架构 I/O 密集型 Java Web 服务

ios - 如果在 Swift 中使用 Router 和 MVVM,谁负责配置演示文稿的具体细节?

python - SQLAlchemy _asdict() 方法仅返回一列

python - 内存密集型Python程序

C++ - 包含 3 个元素的列表的类

python - FPDF __init__ 在Python中与页眉和页脚结合

javascript - 可以在javascript中显式输入 'properties'或 'fields'吗

architecture - 如何将操作与安全检查分离?