Как получить доступ к свойству класса в декораторе в Python?

Я пытаюсь использовать nose_parameterized проверить и хотите использовать его для метода unittest.

from nose.tools import assert_equal
from nose_parameterized import parameterized
import unittest

Class TestFoo(unittest.TestCase):
      def setUp(self):
           self.user1 = "Bar"
           self.user2 = "Foo"

      @parameterized.expand([
               ("testuser1",self.user1,"Bar"),
               ("testuser2",self.user2,"Foo")
                ]
      def test_param(self,name,input,expected):
          assert_equal(input,expected)

Но self не определен в функции декоратора. Есть ли обходной путь для этого? Я знаю, что могу использовать глобальные переменные класса, но мне нужно использовать переменные в setUp,

2 ответа

Решение

Одним из обходных путей будет использование строки, содержащей имя атрибута в декораторе, и getattr в тестовой функции:

@parameterized.expand([
           ("testuser1", "user1", "Bar"),
           ("testuser2", "user2", "Foo")
            ])
def test_param(self, name, input, expected):
    assert_equal(getattr(self, input), expected)

При таком подходе test_param предполагает, что значение его input Аргумент - это имя атрибута, значение которого должно быть проверено expected,

Декоратор не запускается, когда кажется, что он будет запущен. В следующем примере:

class spam:
    @eggs
    def beans( self ):
        pass

помните, что использование декоратора - это то же самое, что сказать:

beans = eggs( beans )

внутри spam объем сразу после defСамо заявление выполняется. Когда это defзаявление выполнено? В то время класс и его методы определены. Декоратор изменяет определение метода на уровне класса spam.beans, а не значение уровня экземпляраself.beans, И, конечно, это происходит задолго до того, как будут созданы какие-либо экземпляры этого класса, то есть до ссылки на какой-либо конкретный экземпляр,selfимеет смысл.

Если вы хотите прикрепить определенный вызываемый (например, модифицированныйtest_paramвызываемый, который имеет определенные аргументы, предварительно запеченные в нем с помощьюfunctools.partial) к примеру selfвы, конечно, можете сделать это внутри одного из методов экземпляра (например, __init__ или же setUp).

Некоторые люди будут описывать код определения класса как происходящий во "время анализа", а код уровня экземпляра как происходящий во время выполнения. Вы можете или не можете найти это полезным способом обдумать это, хотя на самом деле почти все это "время выполнения" в Python.

Другие вопросы по тегам