简体   繁体   English

通常在python中从Base创建Derived类

[英]Universally create Derived class from Base in python

Found some questions on SO but still have no answer... There is a data class 在SO上发现了一些问题,但仍然没有答案......有一个数据类

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

There is a getter class which is supposed to read these data from different sources 有一个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 []

I need to have a Proxy class with more options like 我需要一个具有更多选项的Proxy类

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

Now I want to improve FileProxyGetter as follows: 现在我想改进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

So how do I cast or create an instance of derived class from base class in Python universally. 那么如何在Python中普遍地从基类中转换或创建派生类的实例 It would be better if no changes to the classes needed. 如果不需要对类进行更改会更好。

Or can you suggest more pythonic way of developing such relationships and architecture ? 或者你能建议更多的pythonic方式来发展这种关系和架构吗?

You can use inheritance: 您可以使用继承:

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)

but it's probably more useful in this case to use composition. 但在这种情况下使用合成可能更有用。

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: A dirty trick in python to switch the type of an object: 编辑: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

Another dirty trick for two objects of different types to share the same state: 两个不同类型的对象共享相同状态的另一个脏技巧:

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

However, these tricks, while possible in Python, I would not call them pythonic nor a good OO design. 然而,这些技巧,虽然可能在Python中,我不会称它们为pythonic,也不是一个好的OO设计。

Another possibility in Python 3.x and up, which had removed "unbound method" in place of using regular function: 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