【发布时间】:2016-08-03 04:13:54
【问题描述】:
我正在尝试为包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 = 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() 类方法。
【问题讨论】:
-
您提供的代码不包含对任何名为
type_variants的变量的引用,但原始声明除外。那么它怎么可能在这段代码中被修改或“填充”或以任何方式访问呢?无论 Python 版本如何,这个问题都适用。在 Python2 的情况下,它必须在其他地方被填充。您的列表是否遗漏了重要内容? -
@PaulCornelius:是的,我确实忽略了与
type_variantsdict 交互的类方法。MIMETypes有调用add()填充字典的方法。 -
“静态类”是什么意思?这在其他语言中可能意味着某些东西(其含义取决于语言),但在 Python 中,该形容词不能应用于该名词。
-
@user2357112 只是在没有实例化的情况下使用该类。该代码执行类似于
Types['something']而不是types = Types()然后types['something']
标签: python class import static