How would you determine where each property and method of a Python class is defined?

前端 未结 3 369
旧巷少年郎
旧巷少年郎 2021-01-14 11:41

Given an instance of some class in Python, it would be useful to be able to determine which line of source code defined each method and property (e.g. to implement

相关标签:
3条回答
  • 2021-01-14 11:58

    You are looking for the inspect module, specifically inspect.getsourcefile() and inspect.getsourcelines(). For example

    a.py:

    class Hello(object):
        def say(self):
           print 1
    
    >>> from a import Hello
    >>> hi = Hello()
    >>> inspect.getsourcefile(hi.say)
    a.py
    >>> inspect.getsourcelines(A, foo)
    (['   def say(self):\n        print 1\n'], 2)
    

    Given the dynamic nature of Python, doing this for more complicated situations may simply not be possible...

    0 讨论(0)
  • 2021-01-14 12:00

    You are looking for the undocumented function inspect.classify_class_attrs(cls). Pass it a class and it will return a list of tuples ('name', 'kind' e.g. 'method' or 'data', defining class, property). If you need information on absolutely everything in a specific instance you'll have to do additional work.

    Example:

    >>> import inspect
    >>> import pprint
    >>> import calendar
    >>> 
    >>> hc = calendar.HTMLCalendar()
    >>> hc.__class__.pathos = None
    >>> calendar.Calendar.phobos = None
    >>> pprint.pprint(inspect.classify_class_attrs(hc.__class__))
    [...
     ('__doc__',
      'data',
      <class 'calendar.HTMLCalendar'>,
      '\n    This calendar returns complete HTML pages.\n    '),
     ...
     ('__new__',
      'data',
      <type 'object'>,
      <built-in method __new__ of type object at 0x814fac0>),
     ...
     ('cssclasses',
      'data',
      <class 'calendar.HTMLCalendar'>,
      ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']),
     ('firstweekday',
      'property',
      <class 'calendar.Calendar'>,
      <property object at 0x98b8c34>),
     ('formatday',
      'method',
      <class 'calendar.HTMLCalendar'>,
      <function formatday at 0x98b7bc4>),
     ...
     ('pathos', 'data', <class 'calendar.HTMLCalendar'>, None),
     ('phobos', 'data', <class 'calendar.Calendar'>, None),
     ...
     ]
    
    0 讨论(0)
  • 2021-01-14 12:15

    This is more-or-less impossible without static analysis, and even then, it won't always work. You can get the line where a function was defined and in which file by examining its code object, but beyond that, there's not much you can do. The inspect module can help with this. So:

    import ab
    a = ab.A()
    meth = a.x
    # So, now we have the method.
    func = meth.im_func
    # And the function from the method.
    code = func.func_code
    # And the code from the function!
    print code.co_firstlineno, code.co_filename
    
    # Or:
    import inspect
    print inspect.getsource(meth), inspect.getfile(meth)
    

    But consider:

    def some_method(self):
        pass
    ab.A.some_method = some_method
    ab.A.some_class_attribute = None
    

    Or worse:

    some_cls = ab.A
    some_string_var = 'another_instance_attribute'
    setattr(some_cls, some_string_var, None)
    

    Especially in the latter case, what do you want or expect to get?

    0 讨论(0)
提交回复
热议问题