отдельные классы, использующие `with` в Python - PullRequest
0 голосов
/ 18 февраля 2011

Если у вас есть следующий класс:

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 Ответ

1 голос
/ 18 февраля 2011

Я не уверен, что это тот тип хакерских атак, которые вы ищете ...

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, но это действительно углубляется в редко исследуемый модуль в библиотеке.

...