Why does the Python help function applied to an instance return a page about the parent class in some cases and not it others?

被刻印的时光 ゝ 提交于 2020-01-04 02:16:08

问题


I'm trying to understand how to get useful results when the help function is used to interrogate objects created in my code. I'm puzzled by different behavior for different classes.

Cls1 = type( 'FirstClass', (str,), {'__doc__':'My new class'})
inst1 = Cls1('Hello World')

Cls2 = type( 'SecondClass', (object,), {'__doc__':'My second new class'})
inst2 = Cls2( )

help(inst1) yields No Python documentation found for 'Hello World', while help(inst2) yields:

Help on SecondClass in module __main__ object:

class SecondClass(builtins.object)
 |  My second new class
 |  
...

I would like to create a class based on str and be able to have useful messages displayed by the help function: is there a simple way of achieving this?


回答1:


If you want to create a subclass of str and show the hints with help built-in, you can use docstrings. For instance the following subclass

class NewString(str):
    """This is a brand new implementation of string type"""
    def test_method(self):
        """This is a test method in the new implementation"""
        pass

has the following output on help(NewString)

class NewString(builtins.str)
 |  This is a brand new implementation of string type
 |  
 |  Method resolution order:
 |      NewString
 |      builtins.str
 |      builtins.object
 |  
 |  Methods defined here:
 |  
 |  test_method(self)
 |      This is a test method in the new implementation
...

But as for all instances of string the help method will not be useful.

The reason it fails is that when passing a str to help build-in it is treated as the name of a function, and as there obviously is not a function named Hello World it shows an error.

Running the following help('help') will output:

Help on _Helper in module _sitebuiltins object:

help = class _Helper(builtins.object)
 |  Define the builtin 'help'.
 |  
 |  This is a wrapper around pydoc.help that provides a helpful message
 |  when 'help' is typed at the Python interactive prompt.
 |  
 |  Calling help() at the Python prompt starts an interactive help session.
 |  Calling help(thing) prints help for the python object 'thing'.
...

which is the help on help.




回答2:


I'm not sure about the convention here, but after searching through the pydoc code I would like to provide a more detailed answer to my own question (the pydoc help text is not very informative on the details). The

When passed an argument with type matching type(""), help checks to see if the argument is:

  • in the list ['keywords', 'symbols', 'topics', 'modules', 'modules *', 'True', 'False', 'None'];
  • a keyword (e.g. "from");
  • a symbol (e.g. '%', '<');
  • a topic (e.g. 'FUNCTIONS', 'METHODS');

This is done in the pydoc.Helper.help method. If a match is found, some specific help text is returned.

If none of the above conditions hold, the program flow continues and the object is passed via pydoc.render_doc to the pydoc.resolve function. Here, if the object is an instance of str (including instances of sub-classes, as interpreted by the built-in function isinstance, the pydoc.resolve function attempts to locate a module defined by the value of the argument, and raises an ImportError exception if there is none.

Hence, help('METHODS') provides help on python methods, while help(Cls1('METHODS')) returns an error (where Cls1 is as defined in the question).

This explains the behaviour I see. To me, the use of the isinstance test in pydoc.resolve, as opposed to the type("") test used in pydoc.Helper.help, appears to be an unnecessary inconsistency. There could, of course, be many reasons for this that I'm not aware of, so I've raised a new question focussed on this issue here.



来源:https://stackoverflow.com/questions/59431957/why-does-the-python-help-function-applied-to-an-instance-return-a-page-about-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!