简体   繁体   English

子类_​​_init__看不到超类按条件导入的模块

[英]Subclass __init__ not seeing superclass conditonally-imported module

I have a conditional import in a self-initialized instance of a superclass, but subclass cannot see the module (python 2.7): 我在超类的自初始化实例中有条件导入,但是子类看不到模块(python 2.7):

class A(object):
    def __init__(self, arg1):
        self.attr1 = self.method1(arg1)

    def method1(self, arg1):
        if arg1 == 'foo':
           import amodule
           return amodule.method1()
        else:
            return 'not a dependency on foo'


class B(A):
    def __init__(self, arg1):
        super(B, self).__init__(arg1)
        if arg1 == 'foo':
            self.attr2 = self.method2(self.attr1)

    def method2(self, attr1):
        return amodule.method2()

if __name__=='__main__':
    b = B("foo")
    print b.attr2

This throws NameError: global name 'amodule' is not defined . 这将引发NameError: global name 'amodule' is not defined a = A("foo") works just fine a = A("foo")正常

Shouldn't the super call have executed import amodule in this case? 在这种情况下, super调用不应该执行import amodule吗? (And using import should have put the module into globals?) (使用import应该将模块放入全局变量吗?)

Doesn't import add /amodule/ to the global namespace of the currently executing module? 不会将add / amodule /导入当前执行模块的全局名称空间吗? ( __main__ )? __main__ )?

No, the module is added to sys.modules but if it was imported locally then you won't have any references to it anymore. 不,该模块已添加到sys.modules但是如果它是在本地导入的,那么您将不再有对其的引用。 ie the name amodule is now gone. 即名称amodule现在不见了。

You could still access the module using sys.modules : 您仍然可以使用sys.modules访问该模块:

def method2(self, attr1):
    import sys
    return sys.modules['amodule'].method2()

Or you could import it using import amodule again and it will be picked up from sys.modules . 或者,您可以再次使用import amodule导入它,它将从sys.modules拾取。


# Here b.py contains
# print('Module b was imported')

def func1():
    print('inside func1')
    import b

def func2():
    print('inside func2')
    import sys
    print(sys.modules['b'])
    import b


def func3():
    print('inside func3')
    import b
    import sys
    print('Deleted b')
    del sys.modules['b']
    import b


func1()
print()
func2()
print()
func3()

Demo: 演示:

inside func1
Module b was imported

inside func2
<module 'b' from '/Users/ashwini/py/b.py'>

inside func3
Deleted b
Module b was imported

Try putting import amodule on the first line of the program. 尝试将import amodule放在程序的第一行。

The reason is that amodule is imported in method1, method2 does not have access. 原因是模块是在method1中导入的,method2没有访问权限。

If you follow your code, you would see you don't reach method1(). 如果您遵循自己的代码,则会看到您未达到method1()。

When you create the object b = B(foo) You go through A. init () becuase the call for super(). 创建对象b = B(foo)您将经历A. init (),因为对super()的调用。 However, your init of class A() doesn't include any import statements. 但是,您的类A()初始化不包含任何导入语句。 Then the A.__init__ part is done, and you continue with B.__init__() . 然后完成A.__init__部分,然后继续B.__init__() The next command is a call to amodule object, which wasn't imported at all. 下一个命令是对模块对象的调用,该对象根本没有导入。

You can add an helper method, which checks if the arg equals 'Foo' and if so import the module. 您可以添加一个辅助方法,该方法检查arg是否等于“ Foo”,以及是否导入模块。 Then add a call to this function in A.__init__() function. 然后在A.__init__()函数中添加对此函数的调用。

On another note, __init__() job is to initialize variables. 另外, __init__()工作是初始化变量。 It shouldn't return anything. 它不应该返回任何东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM