解析循环导入语句的Pythonic方法?

解析循环导入语句的Pythonic方法?,python,pageobjects,Python,Pageobjects,我只是继承了一些让我感到不安的代码:有一个测试库,里面充满了与我们网站上的网页相对应的类,每个网页类都有方法来自动化该网页上的功能 有一些方法可以单击页面之间的链接,从而返回链接页面的类。下面是一个简化的示例: 文件homePageLib.py: class HomePage(object): def clickCalendarLink(self): # Click page2 link which navigates browswer to page2

我只是继承了一些让我感到不安的代码:有一个测试库,里面充满了与我们网站上的网页相对应的类,每个网页类都有方法来自动化该网页上的功能

有一些方法可以单击页面之间的链接,从而返回链接页面的类。下面是一个简化的示例:

文件homePageLib.py:

class HomePage(object):
    def clickCalendarLink(self):
        # Click page2 link which navigates browswer to page2
        print "Click Calendar link"
        # Then returns the page2 object
        from calendarLib import CalendarPage
        return CalendarPage()
文件calendarLib.py:

class CalendarPage(object):
    def clickHomePageLink(self):
        # Click page1 link which navigates browswer to page1
        print "Click Home Page link"
        # Then return the page2 object
        from homePageLib import HomePage
        return HomePage()
import homePageLib

class CalendarPage(object):
    def clickHomePageLink(self):
        [...]
        return homePageLib.HomePage()
这样,脚本文件就可以单击页面并从该方法中获取对象作为返回值,这意味着脚本作者不必在浏览站点时不断实例化新页面。(我觉得这是一个奇怪的设计,但我不能确切地指出原因,除了有一个名为“clickSomeLink”的方法并返回结果页面的对象似乎很奇怪。)

下面的脚本演示了脚本如何在站点中导航:(我插入了
printpage
,以显示页面对象如何更改)

脚本文件:

from homePageLib import HomePage

page = HomePage()    
print page
page = page.clickCalendarLink()
print page
page = page.clickHomePageLink()
print page
将生成以下输出:

<homePageLib.HomePage object at 0x00B57570>
Click Calendar link
<calendarLib.CalendarPage object at 0x00B576F0>
Click Home Page link
<homePageLib.HomePage object at 0x00B57570>
文件calendarLib.py

from homePageLib import HomePage

class CalendarPage(object):
    def clickHomePageLink(self):
        # Click page1 link which navigates browswer to page1
        print "Click Home Page link"
        # Then return the page2 object
        return HomePage()
这将导致以下错误:

>>> from homePageLib import HomePage
Traceback (most recent call last):
  File "c:\temp\script.py", line 1, in ?
    #Script
  File "c:\temp\homePageLib.py", line 2, in ?
    from calendarLib import CalendarPage
  File "c:\temp\calendarLib.py", line 2, in ?
    from homePageLib import HomePage
ImportError: cannot import name HomePage
(关于如何更好地格式化python输出的提示?)


与其延续这种风格,我想找到一种更好的方式。有没有一种Pythonic方法来处理这样的循环依赖项,并且仍然将import语句保留在文件的顶部?

解决这些构造通常涉及以下技术

但是,修复此错误相当简单:

在calendarLib.py中:

class CalendarPage(object):
    def clickHomePageLink(self):
        # Click page1 link which navigates browswer to page1
        print "Click Home Page link"
        # Then return the page2 object
        from homePageLib import HomePage
        return HomePage()
import homePageLib

class CalendarPage(object):
    def clickHomePageLink(self):
        [...]
        return homePageLib.HomePage()
模块级的代码在导入时执行。使用来自[…]导入[…]的
语法需要完全初始化模块才能成功

一个简单的
导入[…]
不会,因为没有访问任何符号,从而打破了依赖链。

请阅读详细解释。这种方法是由David Beazley在年提出的

尝试像这样将导入放置在顶部

try:
    from homePageLib import HomePage
except ImportError:
    import sys
    HomePage = sys.modules[__package__ + '.HomePage']

这将尝试导入您的
主页
,如果失败,将尝试从缓存加载它

我明白了。为什么会这样?homePageLib仍然导入calendarPageLib,反之亦然。@nathan:有关详细信息,请查看此页。为什么这个多行结构在Python标准库中没有内置的快捷方式?这看起来很粗糙,但实际上是显式的(阅读:遵循PEP20)。非常好<代码>主页
是问题中的一个类,但此答案将其视为一个模块。