python - tutorial - pandas read text
Obtener clase que define el método (4)
Empecé a hacer algo similar, básicamente la idea era verificar cada vez que se implementaba un método en una clase base o no en una subclase. Resultó como lo hice originalmente. No pude detectar cuándo una clase intermedia realmente estaba implementando el método.
Mi solución para esto fue bastante simple en realidad; establecer un atributo de método y probar su presencia más tarde. Aquí hay una simplificación de todo:
class A():
def method(self):
pass
method._orig = None # This attribute will be gone once the method is implemented
def run_method(self, *args, **kwargs):
if hasattr(self.method, ''_orig''):
raise Exception(''method not implemented'')
self.method(*args, **kwargs)
class B(A):
pass
class C(B):
def method(self):
pass
class D(C):
pass
B().run_method() # ==> Raises Exception: method not implemented
C().run_method() # OK
D().run_method() # OK
ACTUALIZACIÓN: En realidad, llame al method()
desde run_method()
(¿no es ese el espíritu?) Y run_method()
que pase todos los argumentos sin modificar al método.
PD: esta respuesta no responde directamente la pregunta. En mi humilde opinión, hay dos razones por las que uno querría saber qué clase definió un método; primero es señalar con el dedo a una clase en el código de depuración (como en el manejo de excepciones), y el segundo es determinar si el método ha sido reimplementado (donde el método es un apéndice destinado a ser implementado por el programador). Esta respuesta resuelve ese segundo caso de una manera diferente.
¿Cómo puedo obtener la clase que definió un método en Python?
Me gustaría que el siguiente ejemplo para imprimir " __main__.FooClass
":
class FooClass:
def foo_method(self):
print "foo"
class BarClass(FooClass):
pass
bar = BarClass()
print get_class_that_defined_method(bar.foo_method)
Gracias Sr2222 por señalar que me estaba perdiendo el punto ...
Aquí está el enfoque corregido que es como el de Alex pero no requiere importar nada. No creo que sea una mejora, a menos que haya una gran jerarquía de clases heredadas, ya que este enfoque se detiene tan pronto como se encuentra la clase de definición, en lugar de devolver toda la herencia como getmro
hace getmro
. Como se dijo, este es un escenario muy poco probable.
def get_class_that_defined_method(method):
method_name = method.__name__
if method.__self__:
classes = [method.__self__.__class__]
else:
#unbound method
classes = [method.im_class]
while classes:
c = classes.pop()
if method_name in c.__dict__:
return c
else:
classes = list(c.__bases__) + classes
return None
Y el Ejemplo:
>>> class A(object):
... def test(self): pass
>>> class B(A): pass
>>> class C(B): pass
>>> class D(A):
... def test(self): print 1
>>> class E(D,C): pass
>>> get_class_that_defined_method(A().test)
<class ''__main__.A''>
>>> get_class_that_defined_method(A.test)
<class ''__main__.A''>
>>> get_class_that_defined_method(B.test)
<class ''__main__.A''>
>>> get_class_that_defined_method(C.test)
<class ''__main__.A''>
>>> get_class_that_defined_method(D.test)
<class ''__main__.D''>
>>> get_class_that_defined_method(E().test)
<class ''__main__.D''>
>>> get_class_that_defined_method(E.test)
<class ''__main__.D''>
>>> E().test()
1
La solución Alex devuelve los mismos resultados. Siempre que se pueda usar el enfoque de Alex, lo usaría en lugar de este.
No sé por qué nadie ha mencionado esto o por qué la respuesta principal tiene 50 votos ascendentes cuando es lento como el infierno, pero también puede hacer lo siguiente:
def get_class_that_defined_method(meth):
return meth.im_class.__name__
Para python 3, creo que esto cambió y tendrás que investigar .__qualname__
.
import inspect
def get_class_that_defined_method(meth):
for cls in inspect.getmro(meth.im_class):
if meth.__name__ in cls.__dict__:
return cls
return None