2017-01-11 4 views
1

Я нашел способ иметь декоратор в классе, иметь декоратор с аргументами, чтобы украсить функцию с помощью args. Но я не могу заставить все это работать вместе. Как я могу сделать эту работу?Декоратор внутри класса с аргументами для функции, которые принимают аргументы

class Printer(): 
    """ 
    Print thing with my ESCPOS printer 
    """ 
    def text(self, text): 
     with open('/dev/usb/lp0', 'wb') as lp0: 
      lp0.write(text.encode('cp437')) 
      lp0.write(b'\n') 
    def command(self, command): 
     with open('/dev/usb/lp0', 'wb') as lp0: 
      lp0.write(command) 
      lp0.write(b'\n') 
    def style(command_before, command_after): 
     """ 
     Send a command before and a command after 
     """ 
     def decorator(func): 
      def wrapper(self, text): 
       print(self) 
       print(text) 
       self.command(command_before) 
       func(text) 
       self.command(command_after) 
      return wrapper 
     return decorator 
    @style((b'\x1D\x42\x31'), (b'\x1D\x42\x32')) #print white on black 
    @style((b'\x1D\x21\x34'), (b'\x1D\y21\x00')) #print bigger 
    def title(self, title_text): 
     self.text(title_text) 

тогда я мог бы использовать его таким образом:

p = Printer() 
p.title('This is an awesome TITLE!!') 

Это даст мне "TypeError: обертку() недостающий 1 необходимый позиционную аргумент: 'текст'"

Но я просто не получится:/

+1

является 'стиль()' должен быть статический метод? Вы не переходите в 'self' –

+0

« стиль », как представляется, предназначен для использования внутри определения класса; что метакласс делает с ним, как только класс определен, кажется, не имеет значения. – chepner

+1

@chepner: Ах. Кажется, я понял. :) Потому что 'style' используется как декоратор, пока класс определяется, он ведет себя как нормальная (несвязанная) функция, а не метод, поэтому он не принимает' self' arg. А это значит, что мы могли бы переместить определение 'style' вне' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' –

ответ

2

Ваш призыв к func должен прочитать func(self, text). Причина в том, что в этом случае func еще не привязан к экземпляру.

Это невозможно в момент создания класса. Нет примера, с которым вы могли бы связать его. Так func в функции обертку просто обычная функция и, следовательно, нуждается в одни и те же аргументы, как вы определили его с

def title(self, title_text) 
    ... 

Я изменил пример как этот

class Printer(): 
    """ 
    Print thing with my ESCPOS printer 
    """ 
    def text(self, text): 
#   with open('/dev/usb/lp0', 'wb') as lp0: 
#    lp0.write(text.encode('cp437')) 
#    lp0.write(b'\n') 
     print('Text', text) 

    def command(self, command): 
#   with open('/dev/usb/lp0', 'wb') as lp0: 
#    lp0.write(command) 
#    lp0.write(b'\n') 
     print('Command', command) 

    def style(command_before, command_after): 
     """ 
     Send a command before and a command after 
     """ 
     def decorator(func): 
      def wrapper(self, text): 
#     print(self) 
#     print(text) 
       print('type of func', type(func)) # see that it is not bound 
       self.command(command_before) 
       func(self, text) # <-- use (self, ...) 
       self.command(command_after) 
      return wrapper 
     return decorator 

    @style((b'\x1D\x42\x31'), (b'\x1D\x42\x32')) #print white on black 
    @style((b'\x1D\x21\x34'), (b'\x1D\y21\x00')) #print bigger 
    def title(self, title_text): 
     self.text(title_text) 
+0

@PM 2Ring Спасибо за подсказку. Я должен был выглядеть более внимательно. – jhp

+0

Точно ответ, на который я смотрел :) и объяснение, которое я искал – Spoutnik16

3

func() в вашем декораторе по-прежнему является несвязанной функцией. Вы должны связать его явно или передать в self явно:

# bind it to self 
func.__get__(self)(text) 

# or simply pass in self directly 
func(self, text) 
Смежные вопросы