subclases sobrecarga privados poo objeto metodos herencia definir como clase atributos python introspection plone python-datamodel

privados - sobrecarga de metodos en python



¿Cómo determinaría dónde se define cada propiedad y método de una clase de Python? (3)

Dada una instancia de alguna clase en Python, sería útil poder determinar qué línea de código fuente definió cada método y propiedad (por ejemplo, para implementar 1 ). Por ejemplo, dado un módulo ab.py

class A(object): z = 1 q = 2 def y(self): pass def x(self): pass class B(A): q = 4 def x(self): pass def w(self): pass

define una función donde (clase, atributo) devuelve una tupla que contiene el nombre de archivo, la clase y la línea en el código fuente que define o subclasifica el attribute . Esto significa la definición en el cuerpo de la clase, no la última tarea debido al entusiasmo excesivo. Está bien si devuelve ''desconocido'' para algunos atributos.

>>> a = A() >>> b = B() >>> b.spigot = ''brass'' >>> whither(a, ''z'') ("ab.py", <class ''a.A''>, [line] 2) >>> whither(b, ''q'') ("ab.py", <class ''a.B''>, 8) >>> whither(b, ''x'') ("ab.py", <class ''a.B''>, 9) >>> whither(b, ''spigot'') ("Attribute ''spigot'' is a data attribute")

Quiero usar esto mientras hago una introspección de Plone, donde cada objeto tiene cientos de métodos y sería realmente útil ordenarlos organizados por clase y no solo alfabéticamente.

Por supuesto, en Python no siempre se puede saber razonablemente, pero sería bueno obtener buenas respuestas en el caso común de código estático en su mayoría.


Está buscando el módulo de inspección , inspeccione específicamente. inspect.getsourcefile() e inspect.getsourcelines() . Por ejemplo

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)

Dada la naturaleza dinámica de Python, hacer esto para situaciones más complicadas simplemente no puede ser posible ...


Esto es más o menos imposible sin un análisis estático, y aun así, no siempre funcionará. Puede obtener la línea donde se definió una función y en qué archivo examinando su objeto de código, pero más allá de eso, no hay mucho que pueda hacer. El módulo de inspect puede ayudar con esto. Asi que:

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)

Pero considera:

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

O peor:

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

Especialmente en este último caso, ¿qué es lo que quiere o espera obtener?


Está buscando la función indocumentada inspect.classify_class_attrs(cls) . Pasarle una clase y le devolverá una lista de tuplas (''name'', ''kind'' eg ''method'' or ''data'', defining class, property) . Si necesita información sobre absolutamente todo en una instancia específica, tendrá que hacer un trabajo adicional.

Ejemplo:

>>> 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), ... ]