2016-03-09 84 views
1

在一个项目中使用hideous RoboClaw Python "library",我似乎无法摆脱他们抛出一堆处理与物理硬件接口的函数和全局变量到文件中的事实。不幸的是,我坚持使用这个库,因为当供应商为他们的板发布一个新的固件时,他们也会在他们的网站上更新这个文件;将它移植到有用的东西将是一个持续的努力。封装导入模块的范围

当我尝试多次导入它时,就会出现问题,一次对于每个连接到USB的电路板。东西(概念),这样将是理想的:

import roboclaw 
class Board: 
    def __init__(self): 
     self.rc = roboclaw 

由于Python解释似乎保持在内存中的每个进口同一模块的参考,我似乎无法得到它的创建中存在不同的命名空间的实例当所有主板不正确地分配给相同的设备文件时,本质上都会吐出各种I/O冲突错误。我似乎能够得到的最接近的是this answer provided by Noctis Skytower,但它仍然没有为每个Board实例创建单独的名称空间。

此外,我曾尝试使用imp(如this)和importlib(如this),虽然这两个导入失败,因为他们无法找到roboclaw.py文件在同一目录下坐在建立动态的进口。

由于我以前从来没有处理过这个问题,所以我应该继续这个方向,这有点不知所措。

+1

哦上帝,太可怕了!我想出了一种方法来覆盖全局命名空间,所以我会立刻发布一个可能的解决方案。 –

回答

1

好吧通常我会谴责黑客就像一个我的建议,但似乎你没有太多的选择,因为那个包的作者显然没有明白object oriented programming的意思,有创造的方式通过直接调用FunctionType()构造器有不同的全球范围内的函数的副本:

​​

这样,它不会影响在所有的模块中的功能,但仍使用自己的名称空间,然后你可以欺骗一个副本模块与此:

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. 
+0

谢谢!我相信这是行得通的 - 至少我从IPython开始工作。但是,当我执行此应用程序时,我从pyserial中获取了一些错误。一旦我确认这些不相关,我会将其标记为已解决。 – Bobby

+0

oh s ** o **我错误,而不是s ** a **错误。好的,我现在停止改变添加。 –