pythonsocketsserializationgetattr

Call a function using getattr in Python


I want to write a simplest program that gives me an opportunity to use sockets and serialization.

The basic idea is to transfer data to server side with the function name and data to process. And after that deserialize this data sent on server side, to call function and perform something. Then send back the response.

Right now data that is sent to server - func name that I need to call, data that I need to process with using that func.

Im using pickle.loads to unpack data and now I have a func name as a str and dictionary to process. If I will hardcode it - it will work.

The func name that I need to call - func. But I want be able to cal any func that will be sent from client side.

I understand that I need to use getattr to be able to do that. But how? I have read couple of questions here and on other websites but still can't figure out what do I need to do.


Solution

  • It's a bit hard to see what exactly you're trying to accomplish without seeing what you've tried so far.

    Nonetheless, if the function you want to call is actually a method on some object, you can use getattr:

    # somestring is a string, but could be any object
    somestring = "valentyn"
    
    # somestring.upper happens to be a method
    method = getattr(somestring, "upper")
    
    # ...which can be called in the usual manner
    print(method())
    

    If you want to call functions that are locally defined, you can use locals():

    def wow():
        return "spam"
    
    # locals() returns a dict of variables and functions that are locally defined
    print(locals()["wow"]())
    

    If you know in advance which functions you want to expose, you could consider making a dict of functions:

    def foo():
        ...
    
    def bar():
        ...
    
    funcs = {"foo": foo, "bar": bar}
    
    funcs["foo"]()
    

    Finally, if the code you want to run is actually sent from the client like you say, your only option is to use eval - however, this will be even less secure than the options above.