擅长:python、mysql、java
<p>如前所述,您的问题来自循环依赖性(两个模块相互依赖),这既是一个一般性设计问题(无论使用何种语言,您都不应该有循环依赖性),也是Python严重支持的问题</p>
<p>虽然存在快速、肮脏的技术解决方法,但这些方法只能掩盖症状,不能解决问题本身。有各种各样的策略来避免循环依赖(比如像在ex4的答案中那样将公共依赖提取到一个不同的模块),并且大多数情况下,您会使用这两者的组合。在您的例子中,非常明显的问题是,您没有充分的理由使<code>allowed</code>模块依赖于全局<code>cursor</code>。简单地说,您应该在这里明确地将dependee作为参数传递给depender ie:</p>
<pre><code>class Depender():
def __init__(self, dependee):
self.dependee = dependee
def dothis(self, arg):
return self.dependee.do_something_with(arg)
</code></pre>
<p>这种策略(称为“依赖注入”)不仅打破了循环依赖,而且使代码更容易在隔离状态下进行测试</p>
<p>现在,代码还有另一个不相关但严重的问题:<code>allowed</code>模块的代码不应该依赖于<code>cursor</code>,而应该依赖于<code>connection</code>对象本身。第一个也是主要的原因是游标是不可重入的,因此如果一个函数使用游标在select查询问题上进行迭代,并且在迭代过程中调用另一个使用相同游标进行任何其他操作的函数,您将得到非常意外的结果。此外,您仍然需要connection对象来处理事务。数据库连接成本很高,但游标是廉价的一次性对象,因此没有理由尝试重用游标</p>