开发者

Python, best way to return/handle complex data from a method

开发者 https://www.devze.com 2023-04-04 19:57 出处:网络
I need to handle a bunch of similar but exclusively ca开发者_如何学Golled function from a single method. e.g. (maybe not a great example)

I need to handle a bunch of similar but exclusively ca开发者_如何学Golled function from a single method. e.g. (maybe not a great example)

class Util(object):
    def method1(self):
        return "method1", [1,2,3]

    def method2(self):
        return "method2", {"1":4, "2":5, "3":6}

    def method3(self):
        return [1,2,3], "method3", {"1":4, "2":5, "3":6}

    def call_method(self, method_func):
        if method_func.__name__ == "method1":
            (name, dict_values) = self.method_func()
        if method_func.__name__ == "method2":
            (name, list_values) = self.method_func()
        if method_func.__name__ == "method3":
            (list_values, name, dict_values) = self.method_func()
        # How best to manage a return for 3 optional, but not inter-dependent values?
        return name, dict_values, list_values

if __name__ = "__main__":
    u = Util()
    (name, dict_values, list_values) = u.call_method(Util.method1)

The call_method() return is what I'm trying to visualize here. I've got a bunch of exclusive sub-calls I need to make and I need to massage them into something that can be returned.

Would it be easier to just stuff them into Util class member variables? And whoever implements u.call_method() will simply need to know what to look for?

Before anyone complains about the design in the first place, it's not mine. I simply need to expose a consistent API and an interested to hear opinons on how to handle a return like this. It's not easily normalized, and though a missing trailing return value will pass the Runtime, a leading one won't.

Any tips would be great! Thank you.


namedtuple is very Pythonic alternative for returning "nameless" tuples

http://docs.python.org/library/collections.html#collections.namedtuple

This way the caller does not need to extract all tuple members if it needs read only some of them.


If you need to group several values often an approach is using a dictionary... i.e. changing your code to:

...
def method1(self):
    return {"name": "method 1",
            "list": [1, 2, 3]}

Something that is possible in Python is to use an object instead of a dictionary to make the code nicer to read:

class Bunch:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

...
def method1(self):
    return Bunch(name="method1",
                 list=[1, 2, 3])

so that the caller can use result.name instead of result["name"].

Another option that recently got standardized in Python is the NamedTuple.


If you can modify the methods:

class Util(object):
    def method1(self):
        return "method1", [1,2,3], None

    def method2(self):
        return "method2", None, {"1":4, "2":5, "3":6}

    def method3(self):
        return "method3", [1,2,3], {"1":4, "2":5, "3":6}

    def call_method(self, method_func):
        return method_func(self)    

if __name__ == "__main__":
    u = Util() 
    (name, dict_values, list_values) = u.call_method(Util.method1)
    # better:
    print u.method1()

And if you can not change:

class Util(object):
    def method1(self):
        return "method1", [1,2,3]

    def method2(self):
        return "method2", {"1":4, "2":5, "3":6}

    def method3(self):
        return "method3", [1,2,3], {"1":4, "2":5, "3":6}

    def call_method(self, method_func):
        results = method_func(self) 
        name = list_ = dict_ = None   
        for obj in results:
            if isinstance(obj, string):
               name = obj
            elif isinstance(obj, list):
               list_ = obj
            elif isinstacne(obj, dict):
               dict_ = obj
        return name, dict_, list_

if __name__ == "__main__":
    u = Util() 
    (name, dict_values, list_values) = u.call_method(Util.method1)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号