2012-01-03 4 views
3

Вид связанные с этим вопрос:Как проверить, существует ли функция (но не унаследована) в python?

https://stackoverflow.com/questions/8708525/how-to-check-if-mako-function-exist

Я хочу, чтобы проверить, если функция существует для данного класса, но не передается по наследству, так что родители могут назвать функцию ребенка, так как в противном случае это приведет к в бесконечной рекурсии ..

редактировать:

это на самом деле дает максимальную ошибку на уровне стека, который является тем же самым.

эквивалентный код будет:

class A(object): 
    def f(x): 
     b = B() 
     b.f() 

class B(A): 
    pass 

a = A() 
a.f() 

я понимаю, что это не чистый или предпочтительнее, но это то, что шаблон переводится, и я не знаю, как проверить это иначе.

+0

Функция ребенка будет автоматически вызвана, поэтому я не вижу смысла в этом. –

+0

Бесконечная рекурсия? Я не думаю, что это возможно. Можете ли вы показать пример того, что вы подразумеваете под этим? – john

+0

ty, добавленный пример – Timmy

ответ

8

Я хочу, чтобы проверить, если функция существует для данного класса, но не наследуется

Да, вы можете проверить словарь класса напрямую. Либо использовать __dict__ атрибут или встроенный vars() функция ::

>>> class A(object): 
     def f(x): 
      pass 

>>> class B(A): 
     def g(x): 
      pass 

>>> 'f' in vars(B) 
False 
>>> 'g' in vars(B) 
True 
+1

, но 'f in vars (A)' будет 'True', даже если' f' является нефункциональной переменной. следует использовать 'type', чтобы проверить, является ли это функцией или нет. –

+1

@ p.kolya Вы, кажется, читаете больше в вопросе, чем было на самом деле ;-) Кроме того, ваша предложенная поправка слишком ограничительна, '' type (f) == type (lambda: 0) '' не будет работать для некоторых видов вызовов. –

2

Если то, что вам нужно, чтобы проверить, является ли метод, определенный непосредственно в классе экземпляра, а не в одном из своих предков, то вы можете попробовать следующее:

import inspect 

def has_method(obj, name): 
    v = vars(obj.__class__) 
    # check if name is defined in obj's class and that name is a method 
    return name in v and inspect.isroutine(v[name]) 

class A: 
    def foo(self): 
     print 'foo' 

class B(A): 
    pass 

b = B() 
a = A() 

print has_method(a, 'foo') # => True 
print has_method(b, 'foo') # => False 
+0

Спасибо, полезный фрагмент кода. – Nishant