Module 模块名重载和导入路径

Module 模块名重载和导入路径,module,import,twisted,testcase,trial,Module,Import,Twisted,Testcase,Trial,下面的代码失败,因为所需的基类twisted.trial.unittest.TestCase不是基类 from twisted.trial import unittest from unittest import TestCase import myapp class Feature(TestCase): def setUp(self): self.callbackCounter = 0 def checkCbCalled(self, expected): se

下面的代码失败,因为所需的基类twisted.trial.unittest.TestCase不是基类

from twisted.trial import unittest
from unittest import TestCase
import myapp

class Feature(TestCase):

  def setUp(self):
    self.callbackCounter = 0

  def checkCbCalled(self, expected):
      self.assertEqual(self.callbackCounter, expected)

  def testTrialCallsDeferred(self):

      d = myapp.buildFeature()
      self.addCleanup(self.checkCbCalled, expected=1)
      def cb(res):
        self.callbackCounter += 1
      d.addCallback(cb).addErrback(self.fail)
      return d           # does not fire because of 'import rules'?
如果我说

from twisted.trial import unittest as trialut
from trialut import TestCase 
或者更好:

from twisted.trial.unittest import TestCase
然后测试将按预期运行,并且trial.unittest.TestCase将触发我的延迟测试

这似乎是本地最近导入的东西应该取代{lib/pythonX.X/unittest}中可用的东西。我理解它必须是基于sys.path或其他隐式或显式的规则。这让我绊倒了太久,因为我没有调用addCleanup,所有测试都通过了,因为返回的延迟实例没有被触发

我违反了一些规则,请建议阅读或其他

谢谢
Mike

很不清楚您希望它如何工作,但听起来您至少对Python中的模块的行为有些困惑

import
语句(有时)从源文件加载模块,然后将本地范围内的名称绑定到该模块对象

因此,当您这样做时:

from twisted.trial import unittest
您正在加载
twisted.trial.unittest
模块,然后绑定本地名称
unittest
模块

这与以下语句没有任何有趣的相互作用:

from unittest import TestCase
它加载
unittest
模块,然后将本地名称
TestCase
绑定到该模块的
TestCase
属性所引用的对象

当您稍后子类化TestCase时:

class Feature(TestCase):
    ...
您在本地范围中直接使用了名称
TestCase
,该名称指的是
unittest
模块定义的
TestCase
类。请注意,它与Twisted的
Twisted.trial.unittest
模块没有任何关系,即使您也加载了该模块。您必须使用它的一个属性才能使用它的功能

改进代码行为的一个改变是完全停止使用标准库
unittest
模块。删除此行:

from unittest import TestCase
并将类定义替换为:

class Feature(unittest.TestCase):
不要因为标准库
unittest
模块共享Twisted
Twisted.trial.unittest
模块的部分名称而感到困惑。它们是具有不同(尽管相似,有时重叠)功能的不同模块。上面示例中的类定义使用的是
twisted.trial.unittest
,因为它位于原始行之后:

from twisted.trial import unittest

一旦您实际使用Twisted的
TestCase
(来自
Twisted.trial.unittest
),而不是标准库的
TestCase
(来自
unittest
),您将在测试方法返回
延迟的
时获得预期的行为。这是因为Twisted提供了此功能,而不是标准库。

我很惊讶trialut import TestCase的
可以正常工作。它是否与来自未来绝对导入的
一起工作?@jrennie。这不起作用的原因是,虽然本地名称“trailut”绑定到unittest模块,但python的导入在导入东西时并不查看本地名称,只查看实际的模块,“trialut”在sys.modules或其搜索路径中不是实际的模块。我想需要稍微澄清一下。“这与下面的陈述没有任何有趣的相互作用”的说法可能是误导性的。通过加载twisted.trial.unittest,可以加载实际的python unittest模块(查看sys.modules['unittest'])。因此,当初始负载绑定到本地名称unittest时;随后的“fromUnitTestImportTestCase”实际上并没有加载unittest模块(它已经被加载)。它只是在已经加载的unittest模块中查找TestCase,并将本地名称TestCase绑定到它。这是真的,但我不认为讨论import语句是否实际加载并执行代码来初始化模块,或者仅仅将已经初始化的模块从sys.modules中拉出会对操作有多大帮助,至少在他克服目前对模块的误解之前是这样。够公平的,JP!在解决这个问题时,我实际上发现在从twisted.trial导入unittest之后,unittest就在sys.modules中,这有点令人不安(直到我发现twisted.trial的unittest反过来又导入了标准的unittest).我输入的主代码没有按预期工作-这是故意指向问题的。第三个(更好的)代码表示解决方案。整个问题围绕本地名称/模块解析。主/第一个代码块表示了我所造成的混淆,因为我假设本地名称unittest将引用通过导入twisted.trial.unittest创建的本地名称“unittest”引用的模块。由于令人困惑的代码在本地名称空间中表示TestCase实际上并没有引用本地unittest,而是引用了从lib/pythonX.X加载的trial.unittest的unittest,您是说我的答案没有解决您的问题吗?还是怎样不幸的是,我理解这一评论和理解原来的问题一样困难(