我正在尝试引入对包 mime 的 python 3 支持并且代码正在做一些我以前从未见过的事情。
有一个类 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
每当导入 mime_types.py
时,都会运行函数 startup()
并执行此操作。
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 = 类型(版本)
。然后,它似乎对此实例不执行任何操作,而仅使用在 load_from_file()
类方法中创建的 mime_types
实例。 mime_types = Types()
。
这种事情隐约让我想起了javascript的类构造。实例mime_types
如何填充Types.type_variants
,以便在像这样导入时。
从 mime 导入类型,类型
可以使用该类的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()
类方法。
最佳答案
如果不发布更多代码,就很难说。我想说的是,我只需进行一些更改(print 语句 -> 函数、basestring
-> str
,在前面添加一个点即可将该包移植到 Python 3)相同的包导入,以及一个非常丑陋的黑客来补偿他们对 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)
关于python - 静态类在导入时初始化。 python 2如何在导入时初始化静态类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38734294/