2012-11-07 44 views
5

Tôi đã một module mà nhập khẩu mỹ (i in nó ở phía trên cùng của các mô-đun có sử dụng nó)Python mô-đun nhập khẩu là Không

from authorize import cim 
print cim 

nào sản xuất:

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

Tuy nhiên sau này trong một gọi phương thức, nó đã quay sang một cách bí ẩn None

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

mà khi chạy chương trình mà cimNone. Mô-đun không bao giờ được gán trực tiếp cho None ở bất kỳ đâu trong mô-đun này.

Bất kỳ ý tưởng nào về điều này có thể xảy ra?

+3

tôi không nghĩ rằng nó có thể trừ khi có nhiều mã hơn bạn đăng ... – wroniasty

+0

Rõ ràng cái gì đó là mất tích, gửi mã chi tiết xin. –

+5

Một nơi nào đó ở giữa, 'c'' phải được sử dụng như một tên biến toàn cầu. –

Trả lời

4

Khi bạn tự nhận xét - có khả năng một số mã không được gán cho tên "cim" trên chính mô đun của bạn - cách để kiểm tra điều này là nếu mô-đun lớn của bạn sẽ được tạo thành "chỉ đọc" cho các mô-đun khác - tôi nghĩ rằng Python cho phép này - (. 20 phút hack)

-

đây - chỉ cần đặt đoạn mã này trong một tập tin "protect_module.py", nhập nó, và gọi "ProtectdedModule() "ở cuối mô-đun của bạn trong đó tên" cim "đang biến mất - nó sẽ cung cấp cho bạn thủ phạm:

""" 
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