与硬件通信时,我使用的软件包的结构与以下内容类似:
channel
__init__.py
transport
__init__.py
flow.py
multiplex.py
network
__init__.py
header.py
addressing.py
现在,我希望能够配置我的软件包,以便可以使用它与两个非常相似的硬件进行通信。例如,当与hw1通信时,我想要adressing.py中的以下内容等效:
from collections import namedtuple
PacketSize = namedtuple('PacketSize', ('header', 'body'))
packet_size = PacketSize(16,256)
在测试hw2时,我想要的是:
from collections import namedtuple
PacketSize = namedtuple('PacketSize', ('header', 'body'))
packet_size = PacketSize(8,256)
软件包中的几乎所有模块对于hw1和hw2都是相同的。但是,对于包中的某些功能和类,我什至可能会略有不同。
我以为可以通过以下结构解决此问题:
channel
__init__.py
transport
__init__.py
flow.py
multiplex.py
network
__init__.py
header.py
addressing.py
hw1
__init__.py
addressing.py
hw2
__init__.py
addressing.py
因此,每个子软件包将包含一个hw1和hw2子软件包,在其中放置了特定于硬件的代码。我已经对channel / network / addressing.py进行了如下编程:
from collections import namedtuple
PacketSize = namedtuple('PacketSize', ('header', 'body'))
if hardware == "hw1":
from hw1.targetprops import *
elif hardware == "hw2":
from hw2.targetprops import *
和channel / network / hw1 / addressing.py像这样:
from ..addressing import PacketSize
packet_size = PacketSize(16,256)
这有意义吗?我认为channel / network / addressing.py很难理解,因为我正在执行导入,然后定义了一个namedtuple,然后继续进行有条件的导入。我可以做得更好吗?
通用方法是否是包装包装的最佳方法?
是否有配置包的标准方法,以便它知道与hw1还是hw2有关?现在,我只有一个全局调用的硬件,如上
if harware == "hw1"
所示。 最佳答案
您应该尝试在某种通用接口后面抽象出与硬件/风味相关的功能。有很多不同的方法可以做到这一点,例如类继承,composition,在对象周围传递,或者---您可能希望做的---甚至是作为全局python模块或对象。
我个人倾向于经常使用组合,因为类继承通常不是天生的,并且可能会分解为多个继承或MixInMadness
。
全局Python模块(或sigleton对象)很吸引人,但是我会避免使用,除非在单个过程中真的只需要其中一个。很好的例子是将其与底层平台绑定在一起,例如,Python os
模块在Windows和Linux上具有相同的界面,但其下层的工作方式却大不相同。将此与您的hw1
和hw2
进行比较。另一个很好的例子是扭曲反应堆,实际上一次只能运行一个。即使这样,大部分Twisted代码也会绕过reactor
对象进行合成。这部分是为了使单元测试成为可能。
对于您的示例,如果hw1或hw2指的是您的程序在其上运行的硬件,则使用全局python模块确实有意义。如果它是指您的程序正在通过例如串行端口或网络与之通信的硬件,则全局模块是错误的方法。您可能有两个串行端口,并且希望在同一过程中与hw1和hw2通话。
有关如何使用全局模块或实际使用全局对象的示例,建议查看how Twisted does it。然后你的模块会做类似
from mypackage import hardware # hw1/hw2 automatically detected
print hardware.packet_size # different for different hardware
要么
# main.py
from mypackage import hw1
hw1.init()
# other.py
from mypackage import hardware # initialized to hw1 in main.py
另一方面,合成或绕过对象看起来像:
hw = mypackage.hw1.hw1factory()
send_data(hw, 'foo') # uses hw.packet_size
hw = mypackage.hw2.hw2factory()
frob = Frobnicator(hw)
frob.frobnicate('foo') # uses hw.packet_size internally
关于python - 调味包装,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25936236/