#python #function #class #static-methods #descriptor
#питон #функция #класс #статические методы #дескриптор #python
Вопрос:
Я написал простой скрипт:
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.print1
и A.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);
}
И версия Python StaticMethod
из руководства по дескриптору HowTo
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.print1
и A.print2
все просто получают функцию, очень похожую на print_pure
, которая определена ниже, верно?
def print_pure(thing):
print(thing)
Комментарии:
1. Это да. То, как вы используете методы, все они являются просто функциями.
Ответ №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
в данном случае, ему требуется первый параметр в качестве ссылки на объект. Эта ссылка передается неявно при вызове метода с объектом.