具有相同参数的class.method class.staticmethod有什么区别?

时间:2019-04-09 07:52:45

标签: python function class static-methods descriptor

我写了一个简单的脚本:

class A:
    def print1(self):
        print(self)

    @staticmethod
    def print2(thing):
        print(thing)

A.print1('123')
A.print2('123')

print(A.print1)
print(A.print2)

输出为:

123
123
<function A.print1 at 0x7f2f4a1778c8>
<function A.print2 at 0x7f2f4a17b510>

首先是或否:现在A.print1A.print2在功能上似乎都一样,对吧?

作为Python在Github上的代码:

/* Bind a function to an object */
static PyObject *
func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
{
    if (obj == Py_None || obj == NULL) {
        Py_INCREF(func);
        return func;
    }
    return PyMethod_New(func, obj);
}

还有Descriptor HowTo Guide中的Python版本StaticMethod

class StaticMethod(object):
    "Emulate PyStaticMethod_Type() in Objects/funcobject.c"

    def __init__(self, f):
        self.f = f

    def __get__(self, obj, objtype=None):
        return self.f

第二个“是”或“否”:A.print1A.print2都只是获得了与下面定义的print_pure类似的功能,对吗?

def print_pure(thing):
    print(thing)

1 个答案:

答案 0 :(得分:1)

如果您要像在代码中那样从类本身调用方法,则“是”没有区别。但是,当您开始使用类的对象调用这些方法时,事情就会开始有所不同。

绑定方法或实例方法是一个与类的对象绑定的函数,始终需要引用该类的对象作为其第一个参数。

类方法是一个与类本身绑定的函数,始终需要将对类本身的引用作为其第一个参数。

静态方法是既不与类也不与类的对象绑定的方法。

即使我喜欢这样做,也可以使用您的代码。

a = A()
a.print2('123') # this will work just fine, since this is a static method
a.print1('123')  # this will give me the TypeError print1() takes 1 positional argument but 2 were given 

由于print1是实例方法或绑定方法,因此在这种情况下用类a的对象调用此方法时,它需要第一个参数作为对该对象的引用。当您使用对象调用方法时,该引用将隐式传递。