Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Variable Scopes Decorators
#1
Hello,

I try to write some Excel functions with xlwings and openpyxl.
For example one function will get details about an item from another Excel file.
Everytime a function is run, it has to open that other Excel file, do its thing and close the file again.

Since I will have many functions that work with other Excel files, I thought I'll do that with an decorator.
I don't have to code right here but it looks something like this:

def excel_wrapper(func):
    def inner(*args, **kwargs):
        open_excel_file('filename')
        dict1 = {...}

        returnvalue = func(*args, **kwargs)

        close_excel_file()
        return returnvalue
    return inner


@excel_wrapper
def get_value(item, value):
    for x in dict1 ...


get_value('banana', 'color')
This results in a NameError because dict1 is not defined.

I tried to move the open_excel_file etc. stuff from the inner function to the decorator function but this gave me the same error.

Since it is not a single variable but several ones, I guess I don't want to make them global.
Reply
#2
You can just add dict1 to the parameters
def excel_wrapper(func):
    def inner(*args, **kwargs):
        open_excel_file('filename')
        dict1 = {...}
 
        returnvalue = func(dict1, *args, **kwargs)
 
        close_excel_file()
        return returnvalue
    return inner
 
 
@excel_wrapper
def get_value(dict1, item, value):
    for x in dict1 ...
 
 
get_value('banana', 'color')
Reply
#3
I can try this earliest tomorrow, but are you sure that this will work?
From my understanding this should result in the same error since dict1 will be defined after def get_value(dict1, item, value):
Reply
#4
I'm sure it will work. The dict1 in the function is only a parameter. It is passed only when the function is called.
oclmedyb likes this post
Reply
#5
Hey, I just wanted to reply that it is working like this.
And it also makes sense to me if I think about it. Think

But lets assume it is not only dict1 but 10 variables I need to pass in, is there a easier/better/prettier way than passing them as 10 arguments?
Reply
#6
oclmedyb Wrote:is there a easier/better/prettier way than passing them as 10 arguments?
Yes you can pass a single class instance containing the variables.
from functools import wraps

class Foo:
    def __init__(self):
        self.spam = 1
        self.eggs = 23
        self.ham = 42

def excel_wrapper(func):
    foo = Foo()
    @wraps(func)
    def inner(x, y):
        return func(foo, x, y)
    return inner

@excel_wrapper
def func(foo, x, y):
    print(foo.eggs + x + foo.ham * y)

func(1000, 2000)
Marbelous and oclmedyb like this post
Reply
#7
Yes this could be useful. Thank you very much!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Decorators @ annotation drcl 3 387 Feb-24-2024, 06:12 AM
Last Post: Gribouillis
  Does @ at sign used for tother than decorators? ggpython000 1 535 Oct-12-2023, 09:08 AM
Last Post: buran
  Decorators and return statements JonEdward 2 1,880 Jul-24-2020, 05:02 PM
Last Post: JonEdward
  How to print cache from Decorators with Memoization OlgaM 2 2,052 Jan-29-2020, 05:06 PM
Last Post: OlgaM
  Python decorators. dodiko1d 0 8,036 Oct-13-2019, 10:23 AM
Last Post: dodiko1d
  Decorators yksingh1097 2 2,507 Aug-14-2018, 01:44 PM
Last Post: yksingh1097
  learning decorators Prince_Bhatia 6 3,297 Aug-13-2018, 02:28 PM
Last Post: Prince_Bhatia
  decorators within decorators mp3909 6 4,240 Apr-02-2018, 09:47 AM
Last Post: hf8bm
  decorators mp3909 9 5,581 Mar-25-2018, 05:28 PM
Last Post: mp3909

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020