在Python中使用`with`的不同类

时间:2011-02-18 01:42:39

标签: python class metaclass with-statement

如果您有以下课程:

class Foo(object):

    def __init__(name):
        self.name = name

你在名为check_foo.py

的文件中使用它
with Foo("naming it"):
    print Foo.name


with Foo("naming another"):
    print Foo.name

如果您导入check_foo并运行dir(check_foo),则只会获得一个check_foo.Foo模块。

我知道PEP 343提到你可以做类似的事情:

with Foo("naming it") as naming_it:
    print naming_it.name

它会在check_foo check_foo.naming_it中正确实例化,但我的问题是可以解决此问题并动态设置名称。

我正在玩一个概念证明,想知道我能用上述想法得到多远。

是否可以使用我传递给Foo的字符串命名实例?

注意:我也了解withhacks。我们不建议我看一下:)

1 个答案:

答案 0 :(得分:1)

我不确定这是否是你正在寻找的那种hackery ......

import inspect

class renameable(object):
  def rename_me(self, new_name):
    for stack_frame in inspect.stack()[1:]:
      frame_object = stack_frame[0] # frame is the first object in the tuple
      for (name, value) in frame_object.f_locals.iteritems():
        if value is self:
          old_name = name
          matched_frame = frame_object
          break
      if matched_frame:
        break
    if matched_frame:
      matched_frame.f_locals[new_name] = matched_frame.f_locals[old_name]
      del matched_frame.f_locals[old_name]

我怀疑这是一个完整的解决方案,但它确实允许您将值的一个绑定更改为名称。它更改绑定到最接近rename_me调用的值的名称。例如:

>>> import blah
>>> x = blah.renameable()
>>> x
<blah.renameable object at 0x1004cb790>
>>> x.rename_me('y')
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> y
<blah.renameable object at 0x1004cb790>
>>>

我不确定这是否比使用withhacks更好或更差,但它确实深入研究了库中一个很少探索过的模块。