2016-08-03 51 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