передать аргумент __enter__ - PullRequest
       3

передать аргумент __enter__

36 голосов
/ 24 февраля 2011

Просто учусь с заявлениями , особенно из этой статьи

Вопрос в том, могу ли я передать аргумент __enter__?

У меня есть такой код:

class clippy_runner:
    def __enter__(self):
        self.engine = ExcelConnection(filename = "clippytest\Test.xlsx")
        self.db = SQLConnection(param_dict = DATASOURCES[STAGE_RELATIONAL])

        self.engine.connect()
        self.db.connect()

        return self

Я хотел бы передать имя файла и param_dict в качестве параметров __enter__.Это возможно?

Ответы [ 4 ]

43 голосов
/ 24 февраля 2011

Нет. Ты не можешь Вы передаете аргументы __init__().

class ClippyRunner:
    def __init__(self, *args):
       self._args = args

    def __enter__(self):
       # Do something with args
       print(self._args)


with ClippyRunner(args) as something:
    # work with "something"
    pass
23 голосов
/ 21 апреля 2012

Да, вы можете получить эффект, добавив немного больше кода.


    #!/usr/bin/env python

    class Clippy_Runner( dict ):
        def __init__( self ):
            pass
        def __call__( self, **kwargs ):
            self.update( kwargs )
            return self
        def __enter__( self ):
            return self
        def __exit__( self, exc_type, exc_val, exc_tb ):
            self.clear()

    clippy_runner = Clippy_Runner()

    print clippy_runner.get('verbose')     # Outputs None
    with clippy_runner(verbose=True):
        print clippy_runner.get('verbose') # Outputs True
    print clippy_runner.get('verbose')     # Outputs None
3 голосов
/ 16 декабря 2016

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

https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager

from contextlib import contextmanager

@contextmanager
def clippy_runner(*args):
    yield

ИМХО, меня смущает, что с помощью contextmanager вы можете предоставить аргументы, но вы не можете предоставить их __enter__

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

Не могли бы вы просто передать значения в __init__ через конструктор класса?

...