类内Python装饰器
我有一个基本上连接到SFTP服务器的类,与这个问题不太相关。 我正在尝试创建一个包装函数/装饰器,它将帮助我消除大量重复代码。 这是一段代码的工作版本:类内Python装饰器,python,python-3.x,wrapper,pysftp,Python,Python 3.x,Wrapper,Pysftp,我有一个基本上连接到SFTP服务器的类,与这个问题不太相关。 我正在尝试创建一个包装函数/装饰器,它将帮助我消除大量重复代码。 这是一段代码的工作版本: def upload_file(self, local_file, destionation_path: str): with pysftp.Connection( host=self.host, username=self.username, password=s
def upload_file(self, local_file, destionation_path: str):
with pysftp.Connection(
host=self.host,
username=self.username,
password=self.password,
cnopts=self.cnopts
) as sftp:
local_file_path = local_file
print(f'Uploading output file: {local_file_path} to remote location: {destionation_path}')
sftp.put(
localpath=local_file_path,
remotepath=destionation_path,
confirm=False
)
我不想用pysftp写这个`。。。。作为sftp在每个功能开始时的一部分。
我试着这样处理这个问题:
def connection(self, function):
def wrapper(*args, **kwargs):
connection = pysftp.Connection(
host=self.host,
username=self.username,
password=self.password,
cnopts=self.cnopts
)
return_val = function(connection, *args, **kwargs)
return return_val
return wrapper
@connection
def upload_file(self, connection, local_file, destionation_path: str):
print(f'Uploading output file: {local_file} to remote location: {destionation_path}')
connection.put(
localpath=local_file,
remotepath=destionation_path,
confirm=False
)
但是,如果是这样声明的话,self参数不能传递给包装器,那么我如何从其他地方调用upload_文件呢?因为连接参数是由decorator实例化的。
如果以其他方式执行此操作,我将非常感谢您提供一些指导,因为我甚至不确定我在寻找什么。
self
应作为包装器
函数中的参数:
def connection(function):
def wrapper(self, *args, **kwargs):
with pysftp.Connection(
host=self.host,
username=self.username,
password=self.password,
cnopts=self.cnopts
) as connection:
return_val = function(connection, *args, **kwargs)
return return_val
return wrapper
无论如何,您可以像@pqans所说的那样将连接传递给构造函数。这是最简单的解决方案,也是我应该做的。我觉得你有点复杂化了
使用上下文管理器在运行时注入依赖项:
with pysftp.Connection(
host=self.host,
username=self.username,
password=self.password,
cnopts=self.cnopts
) as connection:
sftp = MyClass(connection)
sftp.upload_file(local_file, destionation_path)
另一种方法是为类创建上下文管理器并使用依赖项注入模式:
class ContextWrapperClass(object):
def __init__(self, my_ftp_class_instance, *args, **kwargs):
# ... Some code here
self.ftp_operations = my_ftp_class_instance # This could be an instance
def __enter__(self):
self.connection = pysftp.Connection(
host=self.host,
username=self.username,
password=self.password,
cnopts=self.cnopts
)
self.ftp_operations.connection = self.connection
return self.ftp_operations
def __exit__(self, type, value, traceback):
print("Exception has been handled")
self.connection.close()
return True
那么您可以将其用作:
with ContextWrapperClass(MyClass()) as sftp:
# connection is inserted as dependency injection on constructor
sftp.upload_file(local_file, destionation_path)
这是构造函数的典型用法。为什么要创建装饰器?这不是等效的,您应该将上下文管理器与此解决方案一起使用,谢谢!不客气!