GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — CPython-Internals/BasicObject/method/method.md at master · devz-throwable/CPython-Internals Expand file tree/ Copy pathmethod.mdMore file actions 119 lines (80 loc) · 4.8 KB / Copy pathmethod.mdFile metadata and controls119 lines (80 loc) · 4.8 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 # method # contents * [related file](#related-file) * [memory layout](#memory-layout) * [example](#example) * [print](#print) * [fields in PyMethodDef](#fields-in-PyMethodDef) * [free_list](#free_list) * [classmethod](#classmethod) * [staticmethod](#staticmethod) # related file * cpython/Objects/methodobject.c * cpython/Include/methodobject.h * cpython/Python/bltinmodule.c * cpython/Objects/call.c # memory layout There's a type named **builtin_function_or_method** in python, as the type name described, all the builtin function or method defined in the c level belong to **builtin_function_or_method** >>> print <built-in function print> >>> type(print) <class 'builtin_function_or_method'>  # example ## print let's read code snippet first #define PyCFunction_Check(op) (Py_TYPE(op) == &PyCFunction_Type) typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, PyObject *); typedef PyObject *(*_PyCFunctionFastWithKeywords) (PyObject *, PyObject *const *, Py_ssize_t, PyObject *); typedef PyObject *(*PyNoArgsFunction)(PyObject *); The **PyCFunction** is a type in c, any c function with signature(accept two PyObject* as parameters and return a PyObject *) can be cast to type **PyCFunction** // a c function named builtin_print static PyObject * builtin_print(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames); // name "print" is defined inside a c array named builtin_methods, and defined s type PyMethodDef static PyMethodDef builtin_methods[] = { ... {"print", (PyCFunction)(void(*)(void))builtin_print, METH_FASTCALL | METH_KEYWORDS, print_doc}, ... }  a **PyMethodDef** should be attached to a **module** object, and a **self** arugment, and then a **PyCFunctionObject** will be generated what user really interactive with is **PyCFunctionObject**  let's check for more detail of each field the type in **m_self** field is **module**, and type in **m_module** field is **str**  # fields in PyMethodDef ## ml_name as you can see in the above picture, field **ml_name** is the name of the built-in method, it's a c style null terminated string "print" ## ml_meth the real c function pointer that does the job ## ml_flags bit flag indicates how the c function's behave in the python level the function in **call.c** begin with **_PyMethodDef_** will delegate the work to the **PyCFunction**, but with different calling behaviour according to different **ml_flags** for more detail please refer to [c-api Common Object Structures](https://docs.python.org/3/c-api/structures.html) | flag name | flag value | meaning | | - | :-: | -: | | METH_VARARGS | 0x0001| methods type PyCFunction, expects two PyObject* values | | METH_KEYWORDS | 0x0002 | methods type PyCFunctionWithKeywords, expects three parameters: self, args, and a dictionary of all the keyword arguments | | METH_NOARGS | 0x0004 | methods without parameters, need to be of type PyCFunction | | METH_O | 0x0008 | methods with a single object argument, have the type PyCFunction | | METH_CLASS | 0x0010 | the type object will be passed as first parameter, what @classmethod do | | METH_STATIC | 0x0020 | null will passed as first parameter, what @staticmethod do | | METH_COEXIST | 0x0040 | replace existing defination instead of skip | # free_list static PyCFunctionObject *free_list = NULL; static int numfree = 0; #ifndef PyCFunction_MAXFREELIST #define PyCFunction_MAXFREELIST 256 #endif cpython use a buffer pool with size 256 to reuse the deallocated **PyCFunctionObject** object, free_list is a single linked list, all elements are chained by the **m_self** field the similar technique appears in float object, the float object chained through the **ob_type** field, I will not draw again, user who need the graph representation please click the link [float(free_list)](https://github.com/zpoint/CPython-Internals/blob/master/BasicObject/float/float.md#free_list) # classmethod # staticmethod they're more related in **classobject**, I will talk about them later in [class object](https://github.com/zpoint/CPython-Internals/blob/master/BasicObject/class/class.md) |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |