我有一个与外部工具接口的库,并公开了一些基本关键字,可以在机器人框架中使用;这个库是作为python包实现的,我想实现实现复杂逻辑的扩展功能,并在这个包的模块中公开更多的关键字。包给出了测试用例范围,但我不完全确定它是如何工作的。如果我提出一些我想到的方法,那么有更多知识的人能让我知道我在哪条路上,以及我在哪里咆哮错误的树......
使用实例变量 - 如果范围是python解释器将看到当前测试用例导入的包(即,在不同的测试用例中将其视为单独的包而不是单独的实例相同的包),然后在初始化时,我可以将全局变量INSTANCE
设置为self
,然后从包中的另一个模块设置,导入INSTANCE
并使用它。
使用实例字典 - 如果范围是所有导入都看到包相同,我可以使用robot.running.context设置字典键,以便实例字典中有一个项目导入包的每个上下文 - 这意味着我可以使用相同的上下文变量作为基于此的模块中的查找键。 (这个问题的缺点是它会阻止垃圾收集,直到包本身超出范围,并依赖于它在持久范围内。)
我尚未意识到的上下文变量将为我提供范围内的实例。文档搜索起来相当困难,所以我完全有可能会遗漏一些会使这个变得微不足道的东西。同样好的是允许我调用范围内的关键字。
我没有考虑过一些极好的可能性......
那么有人可以帮忙吗?
答案 0 :(得分:1)
归功于机器人框架用户组的Kevin O.,但基本上魔术生活在robot.libraries.BuiltIn.BuiltIn().get_library_instance(library_name)
中,可以像这样使用:
from robot.libraries.BuiltIn import BuiltIn
class SeleniumTestLibrary(object):
def element_should_be_really_visible(self):
s2l = BuiltIn().get_library_instance('Selenium2Library')
element = s2l._element_find(locator, True, False)
答案 1 :(得分:0)
听起来您正在谈论monkeypatching导入的代码,因此导入该包的其他模块也会看到您的运行时修改。 (纠正我,如果我错了;你的问题中有几点我不太关注)
对于简单的包导入,这应该有效:
import my_package
def method_override():
return "Foo"
my_package.some_method = method_override
在这种情况下, my_package
引用导入的模块,而不仅仅是本地名称,因此其他模块将看到重写的方法。
在其他代码已经完成的情况下,这不会起作用
from my_package import some_method
在这种情况下,some_method
是导入位置的本地名称。如果您在其他地方替换该方法,则无法看到该更改。
如果发生这种情况,那么您需要更改源以导入整个模块,或者通过替换方法内部来更深入地修补:
import my_package
def method_override():
return "Foo"
my_package.some_method.func_code = method_override.func_code
此时,方法在任何其他模块中的导入方式并不重要;与该方法关联的代码对象已被替换,您的新代码将运行而不是原始代码。
在这种情况下唯一需要担心的是,在每种情况下都会从同一路径导入模块。 Python解释器将尝试重用现有模块,而不是在从同一路径导入时重新导入和重新初始化它们。
但是,如果您的python路径设置为包含两个目录,请说:' / foo'和' / foo / bar',然后这两个导入
from foo.bar import baz
和
from bar import baz
最终将加载模块两次,并在模块中定义任何对象(方法,类等)的两个版本。如果发生这种情况,那么修补一个不会影响另一个。
如果您需要防范这种情况,那么您可能必须遍历sys.modules,查找导入的包,并修补您找到的每个版本。当然,这只有在所有其他进口已经发生的情况下才能发挥作用,你不能先发挥作用(没有编写导入钩子,但那又是更深层次了:)) / p>
您确定无法分叉原始包并直接扩展吗?这会容易得多:)