2010-11-17 7 views
9

Tôi có giả định chính xác rằng tất cả các hàm (được xây dựng hoặc do người dùng định nghĩa) thuộc cùng một lớp, nhưng lớp đó dường như không bị ràng buộc với bất kỳ biến nào theo mặc định?python 3: cách kiểm tra xem đối tượng có phải là một hàm không?

Làm cách nào để kiểm tra xem đối tượng có phải là một hàm không?

tôi có thể làm điều này tôi đoán:

def is_function(x): 
    def tmp() 
    pass 
    return type(x) is type(tmp) 

Nó không có vẻ gọn gàng, và tôi thậm chí không chắc chắn 100% đó là hoàn toàn chính xác.

+2

Ngoài ra còn có các đối tượng với một phương pháp __call__ có thể được gọi là một hàm. – SiggyF

+1

Tất cả các lớp có thể được gọi là hàm. – PaulMcG

Trả lời

14

trong python2:

callable(fn) 

trong python3 :

isinstance(fn, collections.Callable) 

như Callable là một Abstract Base Class, điều này tương đương với:

hasattr(fn, '__call__') 
+3

Hàm 'callable' được loại bỏ lần đầu tiên trong Python 3.0 và sau đó được đưa trở lại trong Python 3.2 - vì vậy bạn cũng có thể sử dụng nó với Python 3 nếu sử dụng phiên bản mới nhất của trình thông dịch. Xem http://docs.python.org/3/library/functions.html?highlight=callable#callable để biết thêm thông tin. –

1

Bạn có thể làm:

def is_function(x): 
    import types 
    return isinstance(x, types.FunctionType) \ 
     or isinstance(x, types.BuiltinFunctionType) 
+0

nhưng điều này cũng kiểm tra xem nó có cùng lớp không? –

+0

@Version, ý của bạn là gì nếu 'là cùng một lớp'? –

+0

'is' trên các đối tượng kiểu, yikes. Nếu bạn phải sử dụng typechecks rõ ràng, ít nhất là sử dụng 'isinstance()', và tốt nhất là yêu cầu module 'inspect' để làm điều đó thay thế. –

4

Làm thế nào tôi có thể kiểm tra một đối tượng là một chức năng?

là không giống nhau này như kiểm tra cho callables

hasattr(object, '__call__') 

và cũng trong python 2.x

callable(object) == True 
+1

nó cũng áp dụng cho các lớp học, nhưng 1 anyway có vẻ như nhiều hơn trong logic của gõ vịt – kriss

-2
try: 
    magicVariable() 
except TypeError as e: 
    print('was no function') 
+3

-1, bạn không cần phải thực hiện các chức năng để kiểm tra nó. –

+4

Mã của tôi không có nghĩa là * kiểm tra *. Khi bạn có một biến, lý do duy nhất tại sao bạn sẽ kiểm tra nếu nó là một hàm là vì bạn muốn sử dụng nó. Vì vậy, thay vì đầu tư thời gian để kiểm tra trước đó, bạn chỉ nên sử dụng nó như một hàm và xử lý ngoại lệ. – poke

+1

i + 1'ed nó bởi vì trong trường hợp chung, tôi nghĩ rằng bạn đang đúng, nhưng có chắc chắn trường hợp mà người ta muốn biết nếu một trong những là đối phó với một chức năng mà không có bất kỳ ý định thực hiện nó. Metaclasses và trang trí lớp học đến tâm trí. – aaronasterling