2015-01-05 16 views
1

考慮下面的代碼:列表參數,並跳過「自我」在Python 3

args, varargs, varkw, defaults = inspect.getargspec(method) 
if inspect.ismethod(method): 
    args = args[1:] # Skip 'self' 

當運行此上Python 2和添加一些與被跳過(如在評論中提到)。在Python 3中,使用Class.method(即不是instance.method)上的代碼時遇到了問題。該問題與Detecting bound method in classes (not instances) in Python 3類似,但其中的答案不存在。使用inspect.isroutine()inspect.isfunction()打破了非方法的代碼(無自我)。使用hasattr(method, '__self__')不適用於Class.method

我寫了一個小testscript此:

from __future__ import print_function 
import inspect 


def args_without_self(method): 
    args, varargs, varkw, defaults = inspect.getargspec(method) 
    if inspect.ismethod(method): 
     args = args[1:] # Skip 'self' 
    return args 


class Class(object): 

    def method(self, a, b, c): 
     pass 

    @staticmethod 
    def static(a, b, c): 
     pass 

    @classmethod 
    def classmethod(cls, a, b, c): 
     pass 


def function(a, b, c): 
    pass 

instance = Class() 

print(args_without_self(Class.method)) 
print(args_without_self(instance.method)) 
print(args_without_self(Class.static)) 
print(args_without_self(instance.static)) 
print(args_without_self(Class.classmethod)) 
print(args_without_self(instance.classmethod)) 
print(args_without_self(function)) 

該代碼可以使用兩種Python 2和3。但是args_without_self(Class.method)也有在Python 3(和我想避免這種情況,但不打破別人)。 Everythign應打印['a', 'b', 'c']

回答

4

你不能在Python 3上檢測類的方法,因爲它們是從未綁定。他們是只是常規功能

最多,你可以看看他們的qualified name猜測如果他們可能是方法,然後看看第一個參數被命名爲self。啓發式和猜測,換句話說:

if inspect.isfunction(method) and `.` in method.__qualname__ and args[0] == 'self': 
    args = args[1:] # Skip 'self' 
+0

並希望沒有人會說出自己不同:( – hroncok

+0

@hroncok:或嵌套函數,它實際上不是一個方法使用'self'但如侷限性。 。 –