Ошибка декоратора внутри класса в python3

У меня есть проблема в python3, создал декоратор внутри класса и оно не функционирует

 def decorador(self, function):
     def funcion_interna:
         # acciones adicionales que decoran
         function()

 @decorador
 def funcion(self):
     print("saludo")

Ошибка:

TypeError: database_managment() missing 1 required positional argument: 'function

Но если, я лишаю 'self' декоратора, функционируй без проблемы:

 def decorador(function):
     def funcion_interna:
         # acciones adicionales que decoran
         function()

 @decorador
 def funcion(self):
     print("saludo")

Тогда у меня есть сомнение, если правильно то, что я делаю, если есть различный способ это делать, и т.д.

Также я увидел где-то здесь, что есть классы декоратора на специальных методах '__ call __' и '__ get __' нечто похожее..., который я не понимаю много.

Тогда мое сомнение:

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

И также у меня есть сомнение:

Потому что, лишив 'self' декоратора, оно функционирует правильно?

И заранее спасибо за Ваши ответы!!


(Решенный) Actualisacion:

Пробуйте таким образом и функционируй с 'self', но не, если это правильный способ?

def database_managment(self, *args):
    def connect_database(*args):
        self.connection = sqlite3.connect('database/Bank-Data')
        self.cursor = connection.cursor()
        function(*args)
        self.connection.commit()
        self.connection.close()

    return connect_database
0
задан 02.03.2019, 02:05
1 ответ

Хотя в tГ-tulo вопроса ты упоминаешь "внутри класса", cГіdigo, который ты помещаешь как часть вопроса, не показывает никакого класса. С другой стороны этот cГіdigo в общем неправильный, потому что декоратор, которого ты написал, не возвращает ее funciГіn практикантка (и есть ошибка синтаксиса в ней definiciГіn этой funciГіn, потому что нет они parГ©ntesis).

Давайте Предполагать, что, что querГ-схвати делать, это было чем-то как это:

class A:
  def __init__(self, name):
    self.name = name

  def decorador(self, function):
      def funcion_interna():
          print("Decorada empieza")
          function()
          print("Decorada termina")
      return funcion_interna

  @decorador
  def funcion(self):
       print("saludo", self.name)

intenciГіn состоит в том, чтобы определять Ее следовательно декоратор как mГ©todo класса, и использовать этот декоратор, чтобы украшать другие mГ©todos того же класса.

Предыдущее не функционирует, как ты открыл. Так как mГ©todo decorador() ждет два parГЎmetros (self, и function), но потом ты это используешь помещая @decorador, asumirГЎ, что она funciГіn, что появляется detrГЎs serГЎ первый аргумент, который должен перемещать декоратора (tomarГЎ место self) и его faltarГЎ тогда секунду parГЎmetro function.

, Если мы убираем без mГЎs self ее declaraciГіn от декоратора и это оставляем asГ-:

class A:
  def __init__(self, name):
    self.name = name

  def decorador(function):
      def funcion_interna():
          print("Decorada empieza")
          function()
          print("Decorada termina")
      return funcion_interna

  @decorador
  def funcion(self):
       print("saludo", self.name)

Также estarГ - в добро. Хотя этот раз cГіdigo предыдущий не производит ошибки, будучи выполнен, определил класс, что не comportarГЎ правильно. Если мы тестируем в instanciar этот класс, и называть в Ваш mГ©todo funcion мы это видим:

>>> a = A("Pepe")
>>> a.funcion()
TypeError
----> 1 a.funcion()
TypeError: funcion_interna() takes 0 positional arguments but 1 was given

ВїQuГ© pasГі? Что, сделав a.funcion() в действительности, призывается mГ©todo pasГЎndole как первый parГЎmetro (в self) ссылка на объект. А именно, estГЎ выполняя A.funcion(a). Это в свою очередь, так как funciГіn был украшен ее, он переводится в том, что то, что действительно ejecutarГЎ serГЎ funcion_interna(a), а именно, в нее funciГіn помещает он estГЎ происходя как parГЎmetro объект, на котором actГєa. Но она declaraciГіn ее funciГіn практикантка не ждет таково parГЎmetro, и ahГ - ошибка.

Есть, что aГ±adir в funcion_interna() первый parГЎmetro, что serГЎ объект на, тот, который actГєa. Эта funciГіn называет внутри funcion(), и deberГЎ перемещать его tambiГ©n этот объект, итак, funcion() это ждет (это recibirГЎ в self). А именно cГіdigo конец, который sГ - funcionarГЎ:

class A:
  def __init__(self, name):
    self.name = name

  def decorador(function):
      def funcion_interna(obj):
          print("Decorada empieza")
          function(obj)
          print("Decorada termina")
      return funcion_interna

  @decorador
  def funcion(self):
       print("saludo", self.name)

>>> a = A("Pepe")
>>> a.funcion()
Decorada empieza
saludo Pepe
Decorada termina

конечное Замечание

ВїPor quГ© ты хочешь декоратор внутри класса? FuncionarГЎ точно равный, если estГЎ снаружи:

def decorador(function):
    def funcion_interna(obj):
          print("Decorada empieza")
          function(obj)
          print("Decorada termina")
    return funcion_interna

class A:
  def __init__(self, name):
    self.name = name

  @decorador
  def funcion(self):
       print("saludo", self.name)

Эта форма - что-то mГЎs чистильщик сапог, так как у тебя нет внутри класса одного mГ©todo, что не получает self как первый parГЎmetro (то, что может казаться шокирующим тому, кто это читает, и даже производить ошибки в linters и редактора). AdemГЎs таким образом декоратор ты можешь использовать это в других классах.

AmpliaciГіn (отвечая в нее ampliaciГіn за вопрос)

Пользователь печатает Ваш cГіdigo, в котором пробует использовать снова декоратор как один mГ©todo класса, с этим синтаксисом:

def database_managment(self, *args):
    def connect_database(*args):
        self.connection = sqlite3.connect('database/Bank-Data')
        self.cursor = connection.cursor()
        function(*args)
        self.connection.commit()
        self.connection.close()

    return connect_database

и он говорит, что оно он "функционирует".

Верное состоит в том, что этот cГіdigo не может функционировать по двум причинам:

  1. Декоратор имеет mГЎs parГЎmetros, которых deberГ - в. Декоратор sГіlo может получать один parГЎmetro, и aquГ - у него есть self mГЎs *args. Функционируй видимо, потому что *args podrГ, - чтобы быть vacГ - или. Но тогда self не representarГЎ с целью класса, а в нее funciГіn, что будет являться украшенной.
  2. Внутри Декоратора есть призыв к function(*args), которая darГЎ ошибка, потому что function не estГЎ объявленная, один parГЎmetro ни совсем не.

Тем не менее эти ошибки не descubrirГЎn до тех пор, пока не попробует работать одна funciГіn украшенная с этим декоратором. Так как в этом случае cГіdigo - часть программы, которую использует Tk, и которую функции estГЎn присоединенные с кнопками, ошибка не открывает до тех пор, пока не будет нажата одна из этих кнопок. Поэтому программа "тронься без проблем" и смоги думаться, что estГЎ правильный, но fallarГЎ, нажав один botГіn.

Правильный синтаксис для декоратора serГ - в:

def database_managment(function):
    def connect_database(obj, *args):
        self.connection = sqlite3.connect('database/Bank-Data')
        self.cursor = connection.cursor()
        function(obj, *args)
        self.connection.commit()
        self.connection.close()

    return connect_database

, Поскольку мы видим в этом синтаксисе, нет ссылок на self, из-за которого этот декоратор может писать внутри или вне класса, безразличной формы. Я советую снаружи, потому что иметь внутри класса один mГ©todo, что не использовал self serГ - в смущенный.

1
ответ дан 02.12.2019, 06:13