Boying
Boying

Reputation: 1434

How to proxy a class's methods dynamically?

I would like to proxy "all" methods of a class using following code:

import paramiko

class SFTPProxy():
    def __init__(self, sftp):
        self.sftp = TRANSPORT.open_sftp_client()
        for x, y in type(self.sftp).__dict__.items():
            if re.search(r'^__', x):
                continue
            def fn(self, *args, **kwargs):
                return y(self.sftp, *args, **kwargs)
            setattr(SFTPProxy, x, fn)

When I call the method like this:

fooproxy.sftp.listdir()

It works.

When I call the method like this:

fooproxy.listdir()  # this is the method belongs to the proxied class

The program just hangs, is there any shallow problems in the code?

Upvotes: 2

Views: 1279

Answers (1)

user2390182
user2390182

Reputation: 73470

One issue I can see with your approach is that not all values in type(self.sftp).__dict__ are functions. Hence, y(...) will fail. Isn't it simpler and cleaner to override __getattr__:

class SFTPProxy(object):
    def __init__(self, sftp):
        self.sftp = TRANSPORT.open_sftp_client()

    def __getattr__(self, item):
        if hasattr(self.sftp, item):
            return getattr(self.sftp, item)
        raise AttributeError(item)

This will handle all kinds of attributes rather swiftly: instance/class fields, instance/class/static methods.

Upvotes: 1

Related Questions