gpt4 book ai didi

python - 在 Python 中代理一个类

转载 作者:太空狗 更新时间:2023-10-30 03:02:06 25 4
gpt4 key购买 nike

我正在使用 python-mpd2 模块在 GUI 应用程序中控制 Raspberry Pi 上的媒体播放器。因此,我想在后台优雅地处理连接错误和超时(有问题的播放器在 60 秒后断开 MPD 连接)。但是,MPD 模块没有单一的入口点,我可以通过它发送所有命令或检索我可以修补的信息。

我想要一个允许访问所有与 mpd.MPDClient 相同的方法的类,但让我添加我自己的错误处理。换句话说,如果我这样做:

client.play()

并且抛出了连接错误,我想捕获它并重新发送相同的命令。除了必须重新连接到服务器而导致的小延迟之外,用户应该不会注意到任何不对劲。

到目前为止,这是我提出的解决方案。它在我的应用程序中工作,但并没有真正实现我的目标。

from functools import partial
from mpd import MPDClient, ConnectionError

class PersistentMPDClient(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.client = MPDClient()
self.client.connect(self.host, self.port)

def command(self, cmd, *args, **kwargs):
command_callable = partial(self.client.__getattribute__(cmd), *args, **kwargs)
try:
return command_callable()
except ConnectionError:
# Mopidy drops our connection after a while, so reconnect to send the command
self.client._soc = None
self.client.connect(self.host, self.port)
return command_callable()

我可以为每个 MPD 命令向此类添加一个方法,例如:

def play(self):
return self.command("play")

但这似乎远非实现它的最佳方式。

最佳答案

如果您不介意创建一个由所有 91 个字符串构成的命令名称 的列表,您可以按照 this answer 的方式做一些事情.我相信这种方法有很多优点,因为它涉及的魔法更少。

OTOH,91确实很多。所以这是一个自动解决方案,使用自定义 __getattr__,它返回一个包装器:

from functools import partial
import types

class DummyClient(object):
def connect(self, *a, **kw): print 'connecting %r %r' % (a, kw)
def play(self): print 'playing'
def stop(self): print 'stopping'

class PersistentMPDClient(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.client = DummyClient()
self.client.connect(self.host, self.port)

def __getattr__(self, attr, *args):
cmd = getattr(self.client, attr, *args)
if isinstance(cmd, types.MethodType):
# a method -- wrap
return lambda *a, **kw: self.command(attr, *a, **kw)
else:
# anything else -- return unchanged
return cmd

def command(self, cmd, *args, **kwargs):
command_callable = partial(self.client.__getattribute__(cmd), *args, **kwargs)
try:
return command_callable()
except ConnectionError:
# Mopidy drops our connection after a while, so reconnect to send the command
self.client._soc = None
self.client.connect(self.host, self.port)
return command_callable()

c = PersistentMPDClient(hostname, port)
c.play()
c.stop()

在撰写本文时,我注意到@MatToufoutu 发布了一个类似的解决方案(尽管存在一些差异)。我不知道他/她为什么删除它...如果那个答案没有被删除,我很乐意给予它应有的荣誉。

关于python - 在 Python 中代理一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23033982/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com