Декораторы Python в классах

Ваш веб-сервер работает с обычным пользователем www-data (который принадлежит группе www-data), в то время как ваш консольный вызов PHPUnit создал кэш с пользователем и группой вашего пользователя оболочки. Это распространено и не должно вызывать удивления - почему пользователь оболочки должен иметь возможность записывать данные, используя другого пользователя?

Самое простое решение - использовать разные среды, так как вы также можете использовать разные настройки для запуска тестов. или доступ к предоставленным веб-сайтам.

Если вы не хотите использовать разные среды, в документации Symfony есть несколько идей для вашего:

  • использовать одного и того же пользователя для оболочки и веб-сервера (что означает [ 112] больше не должен использоваться)
  • использовать ACL для вашей папки кэша (таким образом, чтобы впоследствии у пользователя www-data и вашего пользователя оболочки были полные права доступа)

123
задан Nathaniel Jones 31 October 2018 в 20:48
поделиться

3 ответа

Будет ли что-то подобное делать то, что вам нужно?

class Test(object):
    def _decorator(foo):
        def magic( self ) :
            print "start magic"
            foo( self )
            print "end magic"
        return magic

    @_decorator
    def bar( self ) :
        print "normal call"

test = Test()

test.bar()

Это позволяет избежать вызова self для доступа к декоратору и оставляет его скрытым в пространстве имен класса как обычный метод.

>>> import stackoverflow
>>> test = stackoverflow.Test()
>>> test.bar()
start magic
normal call
end magic
>>> 

отредактировано в ответьте на вопрос в комментариях:

Как использовать скрытый декоратор в другом классе

class Test(object):
    def _decorator(foo):
        def magic( self ) :
            print "start magic"
            foo( self )
            print "end magic"
        return magic

    @_decorator
    def bar( self ) :
        print "normal call"

    _decorator = staticmethod( _decorator )

class TestB( Test ):
    @Test._decorator
    def bar( self ):
        print "override bar in"
        super( TestB, self ).bar()
        print "override bar out"

print "Normal:"
test = Test()
test.bar()
print

print "Inherited:"
b = TestB()
b.bar()
print

Вывод:

Normal:
start magic
normal call
end magic

Inherited:
start magic
override bar in
start magic
normal call
end magic
override bar out
end magic
238
ответ дан 24 November 2019 в 01:11
поделиться

Объявите во внутреннем классе. Этот раствор довольно тверд и рекомендован.

class Test(object):
    class Decorators(object):
    @staticmethod
    def decorator(foo):
        def magic(self, *args, **kwargs) :
            print("start magic")
            foo(self, *args, **kwargs)
            print("end magic")
        return magic

    @Decorators.decorator
    def bar( self ) :
        print("normal call")

test = Test()

test.bar()

результат:

>>> test = Test()
>>> test.bar()
start magic
normal call
end magic
>>> 
1
ответ дан 24 November 2019 в 01:11
поделиться

То, что вы хотите сделать, невозможно. Возьмем, например, выглядит ли приведенный ниже код действительным или нет:

class Test(object):

    def _decorator(self, foo):
        foo()

    def bar(self):
        pass
    bar = self._decorator(bar)

Он, конечно, недействителен, поскольку self не определен в этой точке. То же самое касается Test , поскольку он не будет определен, пока не будет определен сам класс (который находится в процессе). Я показываю вам этот фрагмент кода, потому что это то, во что преобразуется фрагмент вашего декоратора.

Итак, как вы можете видеть, доступ к экземпляру в таком декораторе на самом деле невозможен, поскольку декораторы применяются во время определение любой функции / метода, к которым они прикреплены, а не во время создания.

Если вам нужен доступ на уровне класса , попробуйте следующее:

class Test(object):

    @classmethod
    def _decorator(cls, foo):
        foo()

    def bar(self):
        pass
Test.bar = Test._decorator(Test.bar)
54
ответ дан 24 November 2019 в 01:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: