2016-01-20 77 views
1

背景:我试图减少测试完成运行所需的时间。防止Python在加载脚本的某些部分时加载

我最近了解到,当Python解释器加载文件时,它会执行它在其中找到的所有代码。 (Ref:https://stackoverflow.com/questions/419163/what-does-if-name-main-do

有没有办法阻止解释器执行文件的某些部分?原因是,我有一个创建会话并将其分配给类属性的脚本。脚本看起来像这样。

def login(): 
    // Gets auth session from an api. This takes some seconds. 
    return // session 

class Something(object): 
    class_session = login() 

现在我试图嘲弄这个登录过程,但是,当我跑我的单元测试(我用鼻子顺便说一句),我认为Python读取,立即执行该脚本,然后尝试之前创建一个会话它会模拟该方法。这需要几秒钟,我的测试随后需要更长的时间才能完成运行(如果这不是流量,请纠正我)。

  • 有没有一种方法可以防止Python在执行脚本时读取它(而不是在函数中包装代码)?
  • 如果是这样,什么是最Pythonic方式来处理呢?
  • 另外,写好测试需要多长时间才能默认运行。我认为这应该是小于秒(不知道我从哪里得到这种印象)。

请分享一些见解,谢谢。

+0

从bla import foo怎么样? – Alex

+0

@Alex这仍然会加载整个脚本。 – dhke

+1

如果'class_session'是一个类属性,那么你可以将它初始化为'None'并且将'Something.class_session = login()'移动到一个方法(甚至是'__init__'),以防止当对象第一次被击中时被调用。 – Jkdc

回答

1

为了在导入文件时保持login()不被击中,它将需要移出类属性空间。你可以把它放在一个方法像下面这样做:

def login(): 
    // Gets auth session from an api. This takes some seconds. 
    return // session 

class Something(object): 
    class_session = None 

    def __init__(self): 
     if Something.class_session is None: # or self.__class__.class_session 
      Something.class_session = login() 

Something.class_session = login()需求是一个函数或方法内,以防止它被进口运行。上面写的方式,login()将在第一次创建Something()时执行。

请参阅answers here了解更多关于模块导入时运行的内容。

1

你需要编写你的代码,以便它不会做太多简单的声明事情。只有当你明确地调用一个函数或实例化一个类时,你的代码才能做“实际工作”。

class Something(object): 
    class_session = login() 

这将创建一个类属性class_session,这显然必须在类被定义的时间发生,否则它不会是一个类属性。这在此时需要执行login()

要正确,只有当一个新的对象实例化做到这一点,将这段代码到构造,使之实例属性:

class Something(object): 
    def __init__(self): 
     self.class_session = login() 

无论是更有意义,有一些是类属性或如果不知道代码应该做什么,实例属性是不可能的。然而,你真的应该延迟所有“真正的工作”,直到明确调用一个函数;在导入模块时触发登录是疯狂的。