Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类内Python装饰器_Python_Python 3.x_Wrapper_Pysftp - Fatal编程技术网

类内Python装饰器

类内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

我有一个基本上连接到SFTP服务器的类,与这个问题不太相关。 我正在尝试创建一个包装函数/装饰器,它将帮助我消除大量重复代码。 这是一段代码的工作版本:

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)

这是构造函数的典型用法。为什么要创建装饰器?这不是等效的,您应该将上下文管理器与此解决方案一起使用,谢谢!不客气!