Python: 多重继承和属性

Python: multiple inheritance and properties

我一直在研究一个 client/server TCP 应用程序,这里有一个粗略的概述:

config_type = namedtuple('config', ['host', 'port'])


class Server:

    def __init__(self, config: config_type):
        self.config = config


class Client:

    def __init__(self, config: config_type):
        self.config = config

现在我正在将此体系结构扩展到其他计算机,因此我正在实施一个 'slave' 服务器,它将 运行 在其他主机上并将消息从主机分发到该主机上的客户端楼主,所以我写了这样的东西:

class SlaveServer(Server, Client):

    def __init__(self, master_server_config: config_type, slave_server_config: config_type):
        Client.__init__(self, master_server_config)
        Server.__init__(self, slave_server_config)

但是,由于我的 ClientServer 类 定义了一个 属性 调用的配置,因此最后的 init 调用似乎获胜:

master = config_type('localhost', 4342)
slave_config = config_type('localhost', 6555)

slave = SlaveServer(master, slave_config)

print(f'master={master}')
print(f'slave_config={slave_config}')
print(f'slave.config={slave.config}')

输出:

master=config(host='localhost', port=4342)
slave_config=config(host='localhost', port=6555)
slave.config=config(host='localhost', port=6555)

这显然会破坏东西。

在这种情况下应该如何使用多重继承?我是否应该确保自己不存在冲突的 属性 名称?也许在这种情况下多重继承是一个坏主意,我应该更改 SlaveServer 以便它不使用继承,而是只有两个属性,serverclient.

如果您拥有其中的所有代码,则可以使用 Python 的 name-mangling 功能: 只需在名称中添加两个 __ 冲突的属性和方法前缀,不要尝试在子 class 上触及它们(就在定义它们的 class 上).

__ 前缀会触发一个 build-time 功能,该功能会以透明的方式更改属性名称以包含 class ,它们被定义为前缀 - 因此ServerClient 都可以看到自己的 __config 属性。如果您尝试在 ClientServer 上访问 .__config,您将得到一个 AttributeError- 但您可以尝试使用损坏的名称来访问它们中的每一个:

from collections import namedtuple


config_type = namedtuple('config', ['host', 'port'])


class Server:

    def __init__(self, config: config_type):
        self.__config = config


class Client:

    def __init__(self, config: config_type):
        self.__config = config


class SlaveServer(Server, Client):

    def __init__(self, master_server_config: config_type, slave_server_config: config_type):
        Client.__init__(self, master_server_config)
        Server.__init__(self, slave_server_config)

在 REPL 上实例化后,我们可以验证两个属性都已保存:


In [65]: a = SlaveServer((0,0), (1,1))

In [67]: print(a._Server__config)
(1, 1)

In [68]: print(a._Client__config)
(0, 0)        

免责声明:我不是在评判您的体系结构,只是向您指出解决方案built-in 多重继承中这种属性访问的语言。即使没有看到您的更多代码,这似乎是一个 text-book 清楚的例子,其中应该使用组合而不是继承。