python: есть ли способ получить код внутри оператора with - PullRequest
2 голосов
/ 08 февраля 2011

Я надеялся, что это сработает:

class A:
    def __enter__(self, code):
       print code

    def __exit__(..):
       pass

и затем:

with A():
   f()
   g()

будет печатать:

f()
g()

В частности, я собираюсь взять этот код и создать из него функцию. Так что я могу сделать: with runInThreads() или with runManyTimesTillSuccess(), ..

Ответы [ 4 ]

6 голосов
/ 08 февраля 2011

Переносимым, определенным языком способом, нет. Тем не менее, модуль withhacks предоставляет несколько примеров хакерских атак, специфичных для CPython, которые позволяют вам создавать самые разные творческие вещи.

Это больше для игры - функции и генераторы по-прежнему являются единственными официальными способами игры с повторно используемыми блоками кода в Python.

3 голосов
/ 08 февраля 2011

Вот как вы можете использовать декоратор с аргументом:

>>> def manytimes(n):
    def decorate(fn):
        for i in range(n):
            fn()
    return decorate

>>> @manytimes(3)
def _():
    print("hello")


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

Почему вы не используете декоратор?

Я только что попробовал (у меня все еще есть Python 2.6.4, но он наверняка будет работать и с более новыми)

def decorate(fn):
    print "Got", fn
    return "Anything"

def foo():
    @decorate
    def bar(): pass
    print bar

foo()
foo()

и это дает:

Got <function bar at 0x01EAD4B0>
Anything
Got <function bar at 0x01EAD4B0>
Anything

, так что вы можете легко сделать:

any code...
@runInThreads
def _():
    whatever...

Вы можете даже определить _ любое количество раз в функции.

PS: Я прочитал ссылку из со взломом , затем подумал об этом и хотел прокомментировать там тоже, только чтобы заметить, что такая же техника уже предложена в комментариях там .

0 голосов
/ 08 февраля 2011

По совету ncoghlan я пошел на http://pypi.python.org/pypi/withhacks и получил код: http://code.google.com/p/ouspg/wiki/AnonymousBlocksInPython?ts=1253546882&updated=AnonymousBlocksInPython

так что я могу сделать:

from blocks import takes_block

@takes_block
def manyTimes(block):
   for i in range(5):
      block()


 with manyTimes():
     print 'a'
     print 'b'

какие распечатки: a b 5 раз.

...