0

Apologies if it is repetitive but I am struggling to find a solution with this. I am trying to write a decorator function below.

  def search_func(sheetname):
    def insider(function):
        def wraper(*args, **kwargs):
            file = openpyxl.load_workbook("C:\\Users\khisr\OneDrive\Documents\TestPage.xlsx")
            currnet_sheet = file[sheetname]
            function(currnet_sheet)
        return wraper
    return insider         


@search_func('Passwords')
def Longin(self, currnet_sheet):
    Name = self.User_name.get() + str(self.Password.get())
    for i in range(1,current_sheet.max_row +1):
       for j in range(1,current_sheet.max_column+1):
           if current_sheet.cell(i,j).value == Name:

The function is called with a button;

self.Button = tk.Button(self.Main_frame, text='Enter', bg = 'green', command = self.Longin)

I get an error

"Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "C:/Users/khisr/OneDrive/Documents/PythonProjects/Dubai_Project/login.py", line 71, in wraper
    function(currnet_sheet)
TypeError: Longin() missing 1 required positional argument: 'currnet_sheet"

Any help or commend is much appreciated.

Cheers

4
  • Your decorator is fine . The issue is with whatever is calling the Longin method. Probably because tk.Button expects what you pass to be function not a method (methods require self). If you want Longin to be part of a class then try turning it into a @staticmethod. Commented Feb 13, 2020 at 14:05
  • Thanks, Can you elaborate on the @staticmethod? At the moment, the @search_func('Passwords') pass the 'Paswords' which is the page, I want the def search_func(sheetname) function to open. How can I pass the page name that needs to be opened using the @staticmethod? Commented Feb 13, 2020 at 14:09
  • 1
    Not the error but you probably want to return in your decorator: return function(currnet_sheet), otherwise if you decorate a method/function that returns something the decorator will consume it. Commented Feb 13, 2020 at 14:11
  • Sorry staticmethod wont work. You use self. Try using a lambda: self.Button = tk.Button(self.Main_frame, text='Enter', bg='green', command=lambda sheet: self.Longin(sheet)) Commented Feb 13, 2020 at 14:14

1 Answer 1

1

Methods are bound to self when looked up on it. When decorating a method, the resulting decorated method is looked up on self, not the underlying method. You need to explicitly pass on the self parameter.

def search_func(sheetname):
  def insider(function):
      def wraper(self):  # the decorated method receives self...
          file = openpyxl.load_workbook("C:\\Users\khisr\OneDrive\Documents\TestPage.xlsx")
          currnet_sheet = file[sheetname]
          function(self, currnet_sheet)  # ...and should pass it on
      return wraper
  return insider

Note that if you want to support not just regular methods, you must (partially) replicate the descriptor protocol.

def search_func(sheetname):
  def insider(function):
      def wrapper(self):  # the decorated method receives self...
          file = openpyxl.load_workbook("C:\\Users\khisr\OneDrive\Documents\TestPage.xlsx")
          currnet_sheet = file[sheetname]
          function.__get__(self, type(self))(currnet_sheet)  # ...and should pass it on
      return wraper
  return insider  
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I tried all the suggestions but I seem to get this error now. File "C:\ProgramData\Anaconda3\lib\tkinter_init_.py", line 1705, in call return self.func(*args) File "C:/Users/khisr/OneDrive/Documents/PythonProjects/Dubai_Project/login.py", line 70, in wraper function.__get__(self, type(self))(currnet_sheet) File "C:/Users/khisr/OneDrive/Documents/PythonProjects/Dubai_Project/login.py", line 78, in Longin for i in range(1,current_sheet.max_row +1): NameError: name 'current_sheet' is not defined
@user3064089 That looks like another problem. It is not related to the code and question here.
It complains about that it doesn't find the "current_sheet' " but as you can see in the code that is passed to the function.
@user3064089: you mean that currnet_sheet? Python is sensitive to typos in variable names. (Like, practically if not definitely all other programming languages.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.