python中命名空间中exec类的定义

2024-10-03 21:24:17 发布

您现在位置:Python中文网/ 问答频道 /正文

此代码段是中集合模块的namedtuple函数python.when我看到了,我不明白。类定义是格式化字符串,名称空间是dict,exec可以编码ogject或string等等,exec class_definition in namespace如何影响命名空间,那exec生成什么?在


Tags: 模块函数字符串名称编码string定义代码段
1条回答
网友
1楼 · 发布于 2024-10-03 21:24:17

我在Python3上执行此操作,但原理与Python2相同。在

假设你在执行死刑

FooBarBaz = namedtuple('FooBarBaz', 'foo bar baz')

在这种情况下,这个代码

^{pr2}$

使用str.format填充类模板,将class_definition设置为字符串,其内容为:

class FooBarBaz(tuple):
    'FooBarBaz(foo, bar, baz)'

    __slots__ = ()

    _fields = ('foo', 'bar', 'baz')

    def __new__(_cls, foo, bar, baz):
        'Create new instance of FooBarBaz(foo, bar, baz)'
        return _tuple.__new__(_cls, (foo, bar, baz))

    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        'Make a new FooBarBaz object from a sequence or iterable'
        result = new(cls, iterable)
        if len(result) != 3:
            raise TypeError('Expected 3 arguments, got %d' % len(result))
        return result

    def __repr__(self):
        'Return a nicely formatted representation string'
        return 'FooBarBaz(foo=%r, bar=%r, baz=%r)' % self

    def _asdict(self):
        'Return a new OrderedDict which maps field names to their values'
        return OrderedDict(zip(self._fields, self))

    def _replace(_self, **kwds):
        'Return a new FooBarBaz object replacing specified fields with new values'
        result = _self._make(map(kwds.pop, ('foo', 'bar', 'baz'), _self))
        if kwds:
            raise ValueError('Got unexpected field names: %r' % kwds.keys())
        return result

    def __getnewargs__(self):
        'Return self as a plain tuple.  Used by copy and pickle.'
        return tuple(self)

    __dict__ = _property(_asdict)

    def __getstate__(self):
        'Exclude the OrderedDict from pickling'
        pass

    foo = _property(_itemgetter(0), doc='Alias for field number 0')

    bar = _property(_itemgetter(1), doc='Alias for field number 1')

    baz = _property(_itemgetter(2), doc='Alias for field number 2')

现在,代码将创建一个新字典,用作exec的全局命名空间:

namespace = dict(__name__='namedtuple_%s' % typename)

我们不使用空字典的原因是,如果有任何跟踪程序将打印出当前模块的__name__,那么它会发现{}设置为{},而不是不存在。在

之后,我们从字符串中执行类定义,并将全局范围作为字典。在

exec(class_definition, namespace)

基本上,这将执行上面的类定义,它定义了一个新的模块全局变量FooBarBaz,该变量存储在namespace字典中,该字典又可以通过以下方式获取:

result = namespace[typename]   # namespace['FooBarBaz']

现在,result是我们新创建的类;然后对它做了一些向导,使其在pickling之后继续存在,然后返回该类。。。在

这段代码可以再次将其赋给变量FooBarBaz:

FooBarBaz = namedtuple('FooBarBaz', 'foo bar baz')

相关问题 更多 >