简体   繁体   中英

Python imported module is None

I have a module that imports fine (i print it at the top of the module that uses it)

from authorize import cim
print cim

Which produces:

<module 'authorize.cim' from '.../dist-packages/authorize/cim.pyc'>

However later in a method call, it has mysteriously turned to None

class MyClass(object):
    def download(self):
        print cim

which when run show that cim is None . The module isn't ever directly assigned to None anywhere in this module.

Any ideas how this can happen?

As you comment it youself - it is likely some code is attributing None to the "cim" name on your module itself - the way for checking for this is if your large module would be made "read only" for other modules -- I think Python allows for this --

(20 min. hacking ) --

Here -- just put this snippet in a "protect_module.py" file, import it, and call "ProtectdedModule()" at the end of your module in which the name "cim" is vanishing - it should give you the culprit:

"""
Protects a Module against naive monkey patching  -
may be usefull for debugging large projects where global
variables change without notice.

Just call the "ProtectedModule"  class, with no parameters from the end of 
the module definition you want to protect, and subsequent assignments to it
should fail.

"""

from types import ModuleType
from inspect import currentframe, getmodule
import sys

class ProtectedModule(ModuleType):
    def __init__(self, module=None):
        if module is None:
            module = getmodule(currentframe(1))
        ModuleType.__init__(self, module.__name__, module.__doc__)
        self.__dict__.update(module.__dict__)
        sys.modules[self.__name__] = self

    def __setattr__(self, attr, value):
        frame = currentframe(1)
        raise ValueError("Attempt to monkey patch module %s from %s, line %d" % 
            (self.__name__, frame.f_code.co_filename, frame.f_lineno))        

if __name__ == "__main__":
    from xml.etree import ElementTree as ET
    ET = ProtectedModule(ET)
    print dir(ET)
    ET.bla = 10
    print ET.bla

就我而言,这与线程怪癖有关: https//docs.python.org/2/library/threading.html#importing-in-threaded-code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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