在项目中使用可怕的RoboClaw Python“库”,我似乎无法克服这样一个事实,即它们抛出了许多函数和全局变量,这些函数和全局变量用于处理与物理硬件的接口到文件中。不幸的是,我一直在使用该库,因为当供应商为其开发板发布新固件时,他们也在网站上更新了该文件。将其移植到有用的东西将是不断的努力。
当我尝试多次导入该问题时,对于连接到USB的每个板一次,都会出现此问题。这样的(从概念上来说)将是理想的:
import roboclaw
class Board:
def __init__(self):
self.rc = roboclaw
由于Python解释器似乎在每次导入时都在内存中维护相同的模块引用,因此我似乎无法获得它来创建存在于单独命名空间中的实例,从而在所有板卡不正确地变成所有类型的I / O冲突错误时会吐出来分配给相同的/dev/ttyACM
设备文件。我似乎能够获得的最接近的答案是Noctis Skytower提供的答案,但它仍然没有为每个Board
实例创建单独的命名空间。
此外,尽管它们都无法导入,因为它们找不到位于同一目录中的文件,但我尝试使用imp
(像这样)和importlib
(像这样)设置动态导入roboclaw.py
。
我应该继续前进的方向有点茫然,因为我以前从未处理过。
好吧,通常我会像我建议的那样谴责黑客,但是似乎您没有太多选择,因为该软件包的作者显然不了解面向对象编程的含义,因此有一种创建函数副本的方法通过直接调用FunctionType()
构造函数来改变全局范围:
from types import FunctionType
from functools import wraps
def copy_func(func,global_namespace):
"copies a function object with the new specified global scope"
c = FunctionType(func.__code__,global_namespace,func.__name__,func.__defaults__,func.__closure__)
try:
c.__kwdefaults__ = func.__kwdefaults__
except AttributeError:pass #this is only for python 3
c = wraps(func)(c) #copy all metadata although there doesn't seem to be any for roboclaw
return c
这样,它根本不影响模块中的功能,但仍使用您自己的名称空间,然后可以使用以下方法欺骗复制模块:
class CopyScope:
def __init__(self,module):
own_scope = self.__dict__
for name,thing in vars(module).items():
if isinstance(thing,FunctionType):
setattr(self, name, copy_func(thing, own_scope))
else:
setattr(self, name, thing)
#you could also do own_scope[name] = .. instead of setattr() but I prefer setattr()
尽管这仅copy_func
适用于所有模块级别的功能,而不适用于可能使用全局语句的任何方法,但我可以想象,如果作者了解什么方法,则根本不需要此方法。
我可以使用以下代码进行测试:
import roboclaw
x = CopyScope(roboclaw)
x.crc_clear()
x.crc_update(4)
print(x._crc)
print(roboclaw._crc) #this will actually raise an error because it isn't defined in the original module yet.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句