2016-08-03 61 views
2

我試圖引入python 3對包mime的支持,代碼正在做一些我從未見過的事情。靜態類在導入時被初始化。 python 2如何初始化導入的靜態類

有一個類Types()在包中用作靜態類。

class Types(with_metaclass(ItemMeta, object)): # I changed this for 2-3 compatibility 

    type_variants = defaultdict(list) 
    extension_index = defaultdict(list) 

    # __metaclass__ = ItemMeta # unnessecary now 

    def __init__(self, data_version=None): 
     self.data_version = data_version 

type_variants defaultdict是什麼是越來越充滿在Python 2而不是在3

它非常似乎被這個類是被稱爲mime_types.py不同的文件時得到填補。

class MIMETypes(object): 
    _types = Types(VERSION) 

    def __repr__(self): 
     return '<MIMETypes version:%s>' % VERSION 

    @classmethod 
    def load_from_file(cls, type_file): 
     data = open(type_file).read() 
     data = data.split('\n') 
     mime_types = Types() 
     for index, line in enumerate(data): 
      item = line.strip() 
      if not item: 
       continue 
      try: 
       ret = TEXT_FORMAT_RE.match(item).groups() 
      except Exception as e: 
       __parsing_error(type_file, index, line, e) 

      (unregistered, obsolete, platform, mediatype, subtype, extensions, 
      encoding, urls, docs, comment) = ret 
      if mediatype is None: 
       if comment is None: 
        __parsing_error(type_file, index, line, RuntimeError) 
       continue 
      extensions = extensions and extensions.split(',') or [] 
      urls = urls and urls.split(',') or [] 
      mime_type = Type('%s/%s' % (mediatype, subtype)) 
      mime_type.extensions = extensions 
      ... 
      mime_type.url = urls 
      mime_types.add(mime_type) # instance of Type() is being filled? 
     return mime_types 

功能startup()正在運行時mime_types.py是進口的,它做到這一點。

def startup(): 
    global STARTUP 
    if STARTUP: 
     type_files = glob(join(DIR, 'types', '*')) 
     type_files.sort() 
     for type_file in type_files: 
      MIMETypes.load_from_file(type_file) # class method is filling Types? 
    STARTUP = False 

這一切對我來說都很奇怪。 MIMETypes類首先在第一行創建一個Types()的實例。 _types = Types(VERSION)。然後它似乎什麼也不做,只使用load_from_file()類方法中創建的mime_types實例。 mime_types = Types()

這類事隱約讓我想起了javascript類的構建。實例mime_types如何填充Types.type_variants,以便當它像這樣導入時。

from mime import Type, Types

類的type_variants defaultdict都可以使用。爲什麼不在python 3中工作?

編輯:

添加額外的代碼顯示type_variants如何填充

(In "Types" Class) 
@classmethod 
def add_type_variant(cls, mime_type): 
    cls.type_veriants[mime_type.simplified].append(mime_type) 

@classmethod 
def add(cls, *types): 
    for mime_type in types: 
     if isinstance(mime_type, Types): 
      cls.add(*mime_type.defined_types()) 
     else: 
      mts = cls.type_veriants.get(mime_type.simplified) 
      if mts and mime_type in mts: 
       Warning('Type %s already registered as a variant of %s.', 
         mime_type, mime_type.simplified) 
      cls.add_type_variant(mime_type) 
      cls.index_extensions(mime_type) 

你可以看到MIMETypes使用add()類方法。

+0

你給出的代碼包含一個名爲除了正本報關'type_variants'任何變量的引用。那麼它怎麼可能在此代碼中以任何方式被修改或「填充」或訪問?這個問題適用於任何Python版本。在Python2的情況下,它必須在其他地方填充。您的列表是否遺漏了重要的東西? –

+0

@PaulCornelius:是的,我忽略了與'type_variants'字典交互的類方法。 'MIMETypes'具有調用'add()'來填充字典的方法。 – thundergolfer

+0

你是什麼意思的「靜態類」?這可能意味着其他語言中的某些內容(含義取決於語言),但在Python中,該形容詞不能應用於該名詞。 – user2357112

回答

2

沒有發佈更多的代碼,這很難說。我會說,我能夠將該軟件包移植到Python 3中,但只做了一些更改(打印語句 - >功能,basestring - >str,在同一軟件包導入之前添加了一個點,並且爲了補償它們的cmp愛:

def cmp(x,y): 
    if isinstance(x, Type): return x.__cmp__(y) 
    if isinstance(y, Type): return y.__cmp__(x) * -1 
    return 0 if x == y else (1 if x > y else -1) 

注意,我甚至不能確定這是正確的

然後

import mime 
print(mime.Types.type_veriants) # sic 

打印出1590項defaultdict


關於您關於MIMETypes._types未被使用的問題,我同意,事實並非如此。

關於你的問題如何填充字典,這很簡單,你已經確定了它的大部分。

import mime 

導入含有線包的__init__.py

from .mime_types import MIMETypes, VERSION 

mime_types.py包括行:

def startup(): 
    global STARTUP 
    if STARTUP: 
     type_files = glob(join(DIR, 'types', '*')) 
     type_files.sort() 
     for type_file in type_files: 
      MIMETypes.load_from_file(type_file) 
    STARTUP = False 

startup() 

而且MIMETypes.load_from_file()具有行:

mime_types = Types() 
#... 
for ... in ...: 
    mime_types.add(mime_type) 

而且Types.add():有一行:

cls.add_type_variant(mime_type) 

而那類方法包括:

cls.type_veriants[mime_type.simplified].append(mime_type) 
+0

是的,我做了同樣的駭客移植到python 3。由於defaultdict爲空而失敗的單元測試。我必須檢查是否只導入它並忽略單元測試是好的。 – thundergolfer

+0

感謝您的幫助。關於你的編輯,我可以看到字典是如何填充的,但是如何填充實例*也填充靜態類。我仍然不明白爲什麼它不適用於我的python 3 – thundergolfer

+0

你還做了什麼移植項目?你是否安裝軟件包並編輯它,或者你是否從Github上下載並編輯它? – thundergolfer