doc for __getattr__ defined attributes

2019-03-29 14:17发布

问题:

I have to customize __getattr__ to call another function to read.

This works well except the help(object.attr) does not work. This code is used in an interactive environment, so the help() becomes important to us.

Is there a better design to achieve same features but with help() working well.

回答1:

The text that is used for "help" is indeed the "__doc__" attribute of an object. The matter is that depending on the object you have, you can't simply set the __doc__ attribute on it.

If what you need is "help(object.attr)" to work (and not that help(object) shows you all possible attributes) it is a bit easier - you should only get shure that whatever __getattr__ returns do hae a properly set docstring.

SInce "it is not working" I'd guess you are returning the internal results of some function call, like in this snippet:

def __getattr__(self, attr):
    if attr == "foo":
        #function "foo" returns an integer
        return foo()
    ...

If you simply would return the function "foo" itself, without calling it, itś docstring would be displayed normally.

What can be done is to wrap the return value in __getattr__ as an object of a dynamically created class wich contains a proper docstring - so, try using somethong like this:

def __getattr__(self, attr):
    if attr == "foo":
        #function "foo" returns an (whatever object)
        result = foo()
        res_type = type(result)
        wrapper_dict = res_type.__dict__.copy()
        wrapper_dict["__doc__"] = foo.__doc__ #(or "<desired documentation for this attribute>")
        new_type = type(res_type.__name__, (res_type,), wrapper_dict)
        # I will leave it as an "exercise for the reader" if the 
        # constructor of the returned object can't take an object
        # of the same instance (python native data types, like int, float, list, can)
        new_result = new_type(result)
    elif ...: 
        ...
    return new_result

This should work - unless I got wrong the motive why hel is not working in the first place - if that is the case, please give some example of what you are returning from __getattr__.



回答2:

You could turn the attribute into a property. The property will automatically use the getter method's docstring as its own. Alternatively, you could supply the doc argument to property().