所以我有
# my decorator factory
def execute_in(directory): # <-- I want this to be a variable's value which can change
def decorator(function):
def wrapper(*args, **kwargs):
os.chdir(directory)
print(directory) # currently is printing None which is my problem
value = function(*args, **kwargs)
os.chdir(home_dir)
return value
return wrapper
return decorator
和
# a function that runs after assigning General.archive_dir a value
@execute_in(General.archive_dir)
def get_data():
print(General.archive_dir) # will print the correct directory name
with open('data.csv', 'r') as f:
rows = [row for row in csv.reader(f, delimiter=',')]
return rows
我的问题是装饰器工厂使用的变量General.archive_dir
的值是在程序启动时实例化的,当其值为None
时。我希望它在调用装饰函数时使用General.archive_dir
的值。我该怎么办?
如果这个问题不清楚,我深表歉意。如果可以的话,请让我知道如何在需要时进行澄清。
答案 0 :(得分:2)
一种解决方案是使用@execute_in
调用lambda
。
directory
内的 wrapper
将成为一个函数,该函数在调用时将返回当前值。
archive_dir = None
# decorator factory
def execute_in(directory_path_getter):
def decorator(function):
def wrapper(*args, **kwargs):
print('from wrapper:', directory_path_getter()) # Notice the function call
value = function(*args, **kwargs)
return value
return wrapper
return decorator
@execute_in(lambda: archive_dir)
def get_data():
...
archive_dir = 'some directory'
print(get_data())
打印:
from wrapper: some directory
from get_data: some directory
['some data']
答案 1 :(得分:1)
如果严格不需要装饰器,则上下文管理器还可以完成临时更改目录的任务。
import os
from contextlib import contextmanager
@contextmanager
def execute_in(directory):
orig_dir = os.getcwd()
os.chdir(directory)
try:
yield
finally:
os.chdir(orig_dir)
使用上下文管理器可以在一种方法中多次更改目录,并且可以嵌套。
settings = {
'archive_dir': './dir'
}
def get_data():
print(os.getcwd())
with execute_in(settings['archive_dir']):
print(' ' + os.getcwd())
with execute_in('bin'):
print(' ' + os.getcwd())
print(' ' + os.getcwd())
print(os.getcwd())
运行时
>>> get_data()
/home/they4kman/.PyCharm2019.2/config/scratches
/home/they4kman/.PyCharm2019.2/config/scratches/dir
/home/they4kman/.PyCharm2019.2/config/scratches/dir/bin
/home/they4kman/.PyCharm2019.2/config/scratches/dir
/home/they4kman/.PyCharm2019.2/config/scratches