当前位置: 首页 > news >正文

Python/C API - 模組,型別,Tuple,例外和引用計數

Python/C API - 模組,型別,Tuple,例外和引用計數

  • 前言
  • Python/C API - Common Object Structures
    • PyObject
    • PyMethodDef
    • PyGetSetDef
  • Python/C API - Module Objects
    • PyModuleDef
    • PyModule_Create
    • PyModule_AddObject
    • PyModule_AddObjectRef
  • Initialization, Finalization, and Threads
    • Py_Initialize
  • Importing Modules
    • PyImport_AppendInittab
    • PyImport_ImportModule
  • Python/C API - Type Objects
    • PyTypeObject
      • tp_getset
      • tp_methods
  • Python/C API - Tuple Objects
    • PyTuple_New
    • PyTuple_SetItem
    • PyTuple_SET_ITEM
  • Useful macros
    • PyDoc_STRVAR
  • Exception
    • PyErr_NewException
    • PyErr_SetString
  • Reference Counting
    • Py_INCREF
    • Py_XINCREF
    • Py_DECREF
    • Py_XDECREF
    • Py_CLEAR

前言

本文介紹在寫Python的C擴展時常用到的Python/C API中關於模組,型別,Tuple,例外和引用計數的函數。

Python/C API - Common Object Structures

PyObject

PyObject

type PyObject
Part of the Limited API. (Only some members are part of the stable ABI.)
All object types are extensions of this type. This is a type which contains the information Python needs to treat a pointer to an object as an object. In a normal “release” build, it contains only the object’s reference count and a pointer to the corresponding type object. Nothing is actually declared to be a PyObject, but every pointer to a Python object can be cast to a PyObject*. Access to the members must be done by using the macros Py_REFCNT and Py_TYPE.

所有的物件都沿伸自PyObject

PyMethodDef

PyMethodDef

type PyMethodDef
Part of the Stable ABI (including all members).
Structure used to describe a method of an extension type. This structure has four fields:const char *ml_name¶
name of the methodPyCFunction ml_meth
pointer to the C implementationint ml_flags
flags bits indicating how the call should be constructedconst char *ml_doc
points to the contents of the docstring

由以下四個欄位定義:

  • ml_name:函數在Python中的名字
  • ml_meth:實作的C函數的地址
  • ml_flags:用於指示方法如何被呼叫。
    • 使用METH_VARARGS表示Python函數將接受positional argument。
    • 如果希望函數能接受keyword(named) argument,可以改為METH_VARARGS | METH_KEYWORDS
  • ml_doc:函數的說明文檔

Extending and Embedding the Python Interpreter中的例子:

// method table
static PyMethodDef SpamMethods[] = {{"system", // namespam_system, // addressMETH_VARARGS, // or "METH_VARARGS | METH_KEYWORDS"// METH_VARARGS: expect the Python-level parameters to be passed in as a tuple acceptable for parsing via PyArg_ParseTuple()// METH_KEYWORDS: the C function should accept a third PyObject * parameter which will be a dictionary of keywords. Use PyArg_ParseTupleAndKeywords() to parse"Execute a shell command."},{NULL, NULL, 0, NULL} // sentinel
};

PyGetSetDef

PyGetSetDef

An optional pointer to a static NULL-terminated array of PyGetSetDef structures, declaring computed attributes of instances of this type.

計算過後的屬性,所以可以理解為函數。

FieldC TypeMeaning
nameconst char *attribute name
getgetterC function to get the attribute
setsetteroptional C function to set or delete the attribute, if omitted the attribute is readonly
docconst char *optional docstring
closurevoid *optional function pointer, providing additional data for getter and setter

PyGetSetDef由以上五個欄位定義:名字name,取值函數get,設值函數set,函數說明doc以及提供給getter和setter的額外資訊closure

Python/C API - Module Objects

PyModuleDef

PyModuleDef

type PyModuleDef
Part of the Stable ABI (including all members).
The module definition struct, which holds all information needed to create a module object. There is usually only one statically initialized variable of this type for each module.PyModuleDef_Base m_base
Always initialize this member to PyModuleDef_HEAD_INIT.const char *m_name
Name for the new module.const char *m_doc
Docstring for the module; usually a docstring variable created with PyDoc_STRVAR is used.Py_ssize_t m_size
Module state may be kept in a per-module memory area that can be retrieved with PyModule_GetState(), rather than in static globals. This makes modules safe for use in multiple sub-interpreters.This memory area is allocated based on m_size on module creation, and freed when the module object is deallocated, after the m_free function has been called, if present.Setting m_size to -1 means that the module does not support sub-interpreters, because it has global state.Setting it to a non-negative value means that the module can be re-initialized and specifies the additional amount of memory it requires for its state. Non-negative m_size is required for multi-phase initialization.See PEP 3121 for more details.PyMethodDef *m_methods
A pointer to a table of module-level functions, described by PyMethodDef values. Can be NULL if no functions are present.PyModuleDef_Slot *m_slots
An array of slot definitions for multi-phase initialization, terminated by a {0, NULL} entry. When using single-phase initialization, m_slots must be NULL.Changed in version 3.5: Prior to version 3.5, this member was always set to NULL, and was defined as:inquiry m_reload
traverseproc m_traverse
A traversal function to call during GC traversal of the module object, or NULL if not needed.This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (Py_mod_exec function). More precisely, this function is not called if m_size is greater than 0 and the module state (as returned by PyModule_GetState()) is NULL.Changed in version 3.9: No longer called before the module state is allocated.inquiry m_clear
A clear function to call during GC clearing of the module object, or NULL if not needed.This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (Py_mod_exec function). More precisely, this function is not called if m_size is greater than 0 and the module state (as returned by PyModule_GetState()) is NULL.Like PyTypeObject.tp_clear, this function is not always called before a module is deallocated. For example, when reference counting is enough to determine that an object is no longer used, the cyclic garbage collector is not involved and m_free is called directly.Changed in version 3.9: No longer called before the module state is allocated.freefunc m_free
A function to call during deallocation of the module object, or NULL if not needed.This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (Py_mod_exec function). More precisely, this function is not called if m_size is greater than 0 and the module state (as returned by PyModule_GetState()) is NULL.Changed in version 3.9: No longer called before the module state is allocated.
  • 第一個參數PyModuleDef_Base m_base固定為PyModuleDef_HEAD_INIT

  • 第二個參數const char *m_name為module的名字

  • 第三個參數const char *m_doc為module的描述文檔

  • 第四個參數Py_ssize_t m_size為module的大小,在多數情況下會被設為-1,表示該module會在全域變數裡維護狀態,不支援sub-interpreters

  • 第五個參數PyMethodDef *m_methods是一個指標,指向module-level函數的表格(method table)

Extending and Embedding the Python Interpreter給出的用法示例如下:

static struct PyModuleDef spammodule = {PyModuleDef_HEAD_INIT,"spam", // name of modulespam_doc, // module documentation, may be NULL-1, // size of per-interpreter state of the module, or -1 if the module keeps state in global variables.SpamMethods // the method table
};

PyModule_Create

PyModule_Create

PyObject *PyModule_Create(PyModuleDef *def)
Return value: New reference.
Create a new module object, given the definition in def. This behaves like PyModule_Create2() with module_api_version set to PYTHON_API_VERSION.

根據傳入的PyModuleDef指標生成Python模組物件。

並且根據Extending and Embedding the Python Interpreter例子中的注釋,它還會將稍早與模組物件關聯的method table插入新建的模組物件中:

// module definition structure
static struct PyModuleDef spammodule = {PyModuleDef_HEAD_INIT,"spam", // name of modulespam_doc, // module documentation, may be NULL // Docstring for the module; usually a docstring variable created with PyDoc_STRVAR is used.-1, // size of per-interpreter state of the module, or -1 if the module keeps state in global variables.SpamMethods // the method table
};
    PyObject* m;// returns a module object, and inserts built-in function objects into the newly created module based upon the table (an array of PyMethodDef structures) found in the module definition// The init function must return the module object to its caller, so that it then gets inserted into sys.modulesm = PyModule_Create(&spammodule);

PyModule_AddObject

PyModule_AddObject

int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)
Part of the Stable ABI.
Similar to PyModule_AddObjectRef(), but steals a reference to value on success (if it returns 0).The new PyModule_AddObjectRef() function is recommended, since it is easy to introduce reference leaks by misusing the PyModule_AddObject() function.

功能與PyModule_AddObjectRef類似,PyModule_AddObjectRef是比較被建議使用的版本。

Extending and Embedding the Python Interpreter中給出的例子:

// PyInit_spam is module’s initialization function
// must be named PyInit_name
// it will be called when python program imports module spam for the first time
// should be the only non-static item defined in the module file!
// if adding "static", variables and functions can only be used in the specific file, can't be linked through "extern"
// PyMODINIT_FUNC declares the function as PyObject * return type, declares any special linkage declarations required by the platform, and for C++ declares the function as extern "C"
PyMODINIT_FUNC
PyInit_spam(void){PyObject* m;// returns a module object, and inserts built-in function objects into the newly created module based upon the table (an array of PyMethodDef structures) found in the module definition// The init function must return the module object to its caller, so that it then gets inserted into sys.modulesm = PyModule_Create(&spammodule);if(m == NULL)return NULL;// if the last 2 arguments are NULL, then it creates a class who base class is Excetion// exception type, exception instance, and a traceback objectSpamError = PyErr_NewException("spam.error", NULL, NULL);// retains a reference to the newly created exception class// Since the exception could be removed from the module by external code, an owned reference to the class is needed to ensure that it will not be discarded, causing SpamError to become a dangling pointer// Should it become a dangling pointer, C code which raises the exception could cause a core dump or other unintended side effectsPy_XINCREF(SpamError);if(PyModule_AddObject(m, "error", SpamError) < 0){// clean up garbage (by making Py_XDECREF() or Py_DECREF() calls for objects you have already created) when you return an error indicator// Decrement the reference count for object o. The object may be NULL, in which case the macro has no effect; otherwise the effect is the same as for Py_DECREF(), and the same warning applies.Py_XDECREF(SpamError);// Decrement the reference count for object o. The object may be NULL, in which case the macro has no effect; otherwise the effect is the same as for Py_DECREF(), except that the argument is also set to NULL.Py_CLEAR(SpamError);// Decrement the reference count for object o.// If the reference count reaches zero, the object’s type’s deallocation function (which must not be NULL) is invoked.Py_DECREF(m);return NULL;}return m;
}

PyModule_AddObjectRef

PyModule_AddObjectRef

int PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
Part of the Stable ABI since version 3.10.
Add an object to module as name. This is a convenience function which can be used from the module’s initialization function.On success, return 0. On error, raise an exception and return -1.Return NULL if value is NULL. It must be called with an exception raised in this case.

value這個PyObject(物件)加到module裡,之後在Python裡就可以透過module.name的方式存取這個物件。

成功時回傳0,否則回傳-1。

Initialization, Finalization, and Threads

Py_Initialize

void Py_Initialize()
Part of the Stable ABI.
Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; see Before Python Initialization for the few exceptions.This initializes the table of loaded modules (sys.modules), and creates the fundamental modules builtins, __main__ and sys. It also initializes the module search path (sys.path). It does not set sys.argv; use PySys_SetArgvEx() for that. This is a no-op when called for a second time (without calling Py_FinalizeEx() first). There is no return value; it is a fatal error if the initialization fails.Note On Windows, changes the console mode from O_TEXT to O_BINARY, which will also affect non-Python uses of the console using the C Runtime.

初始化Python直譯器。如果有程式想用任何其它的Python/C API函數,必須事先調用本函數。

Importing Modules

PyImport_AppendInittab

PyImport_AppendInittab

int PyImport_AppendInittab(const char *name, PyObject *(*initfunc)(void))
Part of the Stable ABI.
Add a single module to the existing table of built-in modules. This is a convenience wrapper around PyImport_ExtendInittab(), returning -1 if the table could not be extended. The new module can be imported by the name name, and uses the function initfunc as the initialization function called on the first attempted import. This should be called before Py_Initialize().

將模組加入內建模組的表格(PyImport_Inittab)中。

  • name:之後使用這個名字來import這個新模組
  • initfunc:初次導入模組時所用的初始化函數

本函數應在Py_Initialize前使用,這樣子名為name的模組的初始化函數initfunc才會自動被調用。

Extending and Embedding the Python Interpreter中給出的例子:

    //add a built-in module, before Py_Initialize//When embedding Python, the PyInit_spam() function is not called automatically unless there’s an entry in the PyImport_Inittab table. To add the module to the initialization table, use PyImport_AppendInittab(), optionally followed by an import of the moduleif(PyImport_AppendInittab("spam", PyInit_spam) == -1){fprintf(stderr, "Error: could not extend in-built modules table\n");exit(1);}

PyImport_ImportModule

PyImport_ImportModule

PyObject *PyImport_ImportModule(const char *name)
Return value: New reference. Part of the Stable ABI.
This is a simplified interface to PyImport_ImportModuleEx() below, leaving the globals and locals arguments set to NULL and level set to 0. When the name argument contains a dot (when it specifies a submodule of a package), the fromlist argument is set to the list ['*'] so that the return value is the named module rather than the top-level package containing it as would otherwise be the case. (Unfortunately, this has an additional side effect when name in fact specifies a subpackage instead of a submodule: the submodules specified in the package’s __all__ variable are loaded.) Return a new reference to the imported module, or NULL with an exception set on failure. A failing import of a module doesn’t leave the module in sys.modules.This function always uses absolute imports.

import一個名為name的模組並回傳,如果有拋出例外或是失敗的話則會回傳NULL

Extending and Embedding the Python Interpreter中給出的例子:

    // Optionally import the module; alternatively,// import can be deferred until the embedded script imports it.PyObject* pmodule = PyImport_ImportModule("spam");if(!pmodule){PyErr_Print();fprintf(stderr, "Error: could not import module 'spam'\n");}

Python/C API - Type Objects

PyTypeObject

Type Objects

type PyTypeObject
Part of the Limited API (as an opaque struct).
The C structure of the objects used to describe built-in types.

PyTypeObject是一個用來描述Python內建型別的C的結構體。

tp_getset

PyTypeObject.tp_getset

struct PyGetSetDef *PyTypeObject.tp_getset
An optional pointer to a static NULL-terminated array of PyGetSetDef structures, declaring computed attributes of instances of this type.For each entry in the array, an entry is added to the type’s dictionary (see tp_dict below) containing a getset descriptor.

PyTypeObject的屬性之一。是一個可選的指標,指向PyGetSetDef陣列,代表本型別計算過後的屬性。

tp_methods

PyTypeObject.tp_methods

struct PyMethodDef *PyTypeObject.tp_methods
An optional pointer to a static NULL-terminated array of PyMethodDef structures, declaring regular methods of this type.For each entry in the array, an entry is added to the type’s dictionary (see tp_dict below) containing a method descriptor.

PyTypeObject的屬性之一。是一個可選的指標,指向PyMethodDef陣列,代表本型別一般的方法。

Python/C API - Tuple Objects

Python/C API - Tuple Objects

PyTuple_New

PyObject *PyTuple_New(Py_ssize_t len)
Return value: New reference. Part of the Stable ABI.
Return a new tuple object of size len, or NULL on failure.

新建一個長度為len的tuple並回傳。

PyTuple_SetItem

int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o)
Part of the Stable ABI.
Insert a reference to object o at position pos of the tuple pointed to by p. Return 0 on success. If pos is out of bounds, return -1 and set an IndexError exception.Note This function “steals” a reference to o and discards a reference to an item already in the tuple at the affected position.

p這個指標所指向的tuple的第pos個位置插入物件o。成功時回傳0,如果pos超過邊界,則回傳-1。

PyTuple_SET_ITEM

void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
Like PyTuple_SetItem(), but does no error checking, and should only be used to fill in brand new tuples.Note This macro “steals” a reference to o, and, unlike PyTuple_SetItem(), does not discard a reference to any item that is being replaced; any reference in the tuple at position pos will be leaked.

PyTuple_SetItem的功能一樣,但不做錯誤檢查,並且只適用於填充新的tuple。

Useful macros

PyDoc_STRVAR

PyDoc_STRVAR

PyDoc_STRVAR(name, str)Creates a variable with name `name` that can be used in docstrings. If Python is built without docstrings, the value will be empty.Use [`PyDoc_STRVAR`](https://docs.python.org/3/c-api/intro.html#c.PyDoc_STRVAR) for docstrings to support building Python without docstrings, as specified in [**PEP 7**](https://peps.python.org/pep-0007/).

創造一個名為name的變數,它可以被當作文檔字串來使用。如:

PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");static PyMethodDef deque_methods[] = {// ...{"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc},// ...
}

Extending and Embedding the Python Interpreter中給出的例子,首先創建一個名為spam_doc的變數:

// Creates a variable with name name that can be used in docstrings. If Python is built without docstrings, the value will be empty.
PyDoc_STRVAR(spam_doc, "Spam module that call system function.");

這個spam_doc便可以作為PyModuleDefm_doc欄位使用:

// module definition structure
static struct PyModuleDef spammodule = {PyModuleDef_HEAD_INIT,"spam", // name of modulespam_doc, // module documentation, may be NULL // Docstring for the module; usually a docstring variable created with PyDoc_STRVAR is used.-1, // size of per-interpreter state of the module, or -1 if the module keeps state in global variables.SpamMethods // the method table
};

Exception

PyErr_NewException

PyErr_NewException

PyObject *PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
Return value: New reference. Part of the Stable ABI.
This utility function creates and returns a new exception class. The name argument must be the name of the new exception, a C string of the form module.classname. The base and dict arguments are normally NULL. This creates a class object derived from Exception (accessible in C as PyExc_Exception).The __module__ attribute of the new class is set to the first part (up to the last dot) of the name argument, and the class name is set to the last part (after the last dot). The base argument can be used to specify alternate base classes; it can either be only one class or a tuple of classes. The dict argument can be used to specify a dictionary of class variables and methods.

創造並返回一個新的exception類別,這個新exception類別繼承自Python的Exception(即C中的PyExc_Exception)。

參數:

  • name:新例外的名字,型式為module.classname
  • base:替代的基礎類別,通常是NULL
  • dict:類別變數和方法的字典,通常是NULL

Extending and Embedding the Python Interpreter中給出的例子:

// define your own new exception
static PyObject* SpamError;
    SpamError = PyErr_NewException("spam.error", NULL, NULL);

PyErr_SetString

PyErr_SetString

void **PyErr_SetString**([PyObject](https://docs.python.org/3/c-api/structures.html#c.PyObject) *type, const char *message)*Part of the [Stable ABI](https://docs.python.org/3/c-api/stable.html#stable).*This is the most common way to set the error indicator. The first argument specifies the exception type; it is normally one of the standard exceptions, e.g. `PyExc_RuntimeError`. You need not increment its reference count. The second argument is an error message; it is decoded from `'utf-8'`.

英文說set the error indicator,其實就是raise exception,發起例外,表示程序在這裡出錯的意思。

其參數有二:

  • type:例外的型別,不需要手動增加其引用計數
  • message:錯誤訊息

Extending and Embedding the Python Interpreter中給出的例子:

PyErr_SetString(SpamError, "System command failed");

Reference Counting

Py_INCREF

Py_INCREF

void Py_INCREF(PyObject *o)
Indicate taking a new strong reference to object o, indicating it is in use and should not be destroyed.This function is usually used to convert a borrowed reference to a strong reference in-place. The Py_NewRef() function can be used to create a new strong reference.When done using the object, release it by calling Py_DECREF().The object must not be NULL; if you aren’t sure that it isn’t NULL, use Py_XINCREF().Do not expect this function to actually modify o in any way.

o標記為正在使用且不可被銷毀。如果用完了o,可以透過Py_DECREF將它釋放掉。

o不可為NULL

Extending and Embedding the Python Interpreter中給出的例子:

    SpamError = PyErr_NewException("spam.error", NULL, NULL);// retains a reference to the newly created exception class// Since the exception could be removed from the module by external code, an owned reference to the class is needed to ensure that it will not be discarded, causing SpamError to become a dangling pointer// Should it become a dangling pointer, C code which raises the exception could cause a core dump or other unintended side effectsPy_XINCREF(SpamError);if(PyModule_AddObject(m, "error", SpamError) < 0){// clean up garbage (by making Py_XDECREF() or Py_DECREF() calls for objects you have already created) when you return an error indicator// Decrement the reference count for object o. The object may be NULL, in which case the macro has no effect; otherwise the effect is the same as for Py_DECREF(), and the same warning applies.Py_XDECREF(SpamError);// Decrement the reference count for object o. The object may be NULL, in which case the macro has no effect; otherwise the effect is the same as for Py_DECREF(), except that the argument is also set to NULL.Py_CLEAR(SpamError);// Decrement the reference count for object o.// If the reference count reaches zero, the object’s type’s deallocation function (which must not be NULL) is invoked.Py_DECREF(m);return NULL;}

Py_XINCREF

Py_XINCREF

void Py_XINCREF(PyObject *o)
Similar to Py_INCREF(), but the object o can be NULL, in which case this has no effect.See also Py_XNewRef().

Py_INCREF類似,但是o可以為NULLoNULL時函數沒有作用。

Py_DECREF

Py_DECREF

void Py_DECREF(PyObject *o)
Release a strong reference to object o, indicating the reference is no longer used.Once the last strong reference is released (i.e. the object’s reference count reaches 0), the object’s type’s deallocation function (which must not be NULL) is invoked.This function is usually used to delete a strong reference before exiting its scope.The object must not be NULL; if you aren’t sure that it isn’t NULL, use Py_XDECREF().Do not expect this function to actually modify o in any way.Warning The deallocation function can cause arbitrary Python code to be invoked (e.g. when a class instance with a __del__() method is deallocated). While exceptions in such code are not propagated, the executed code has free access to all Python global variables. This means that any object that is reachable from a global variable should be in a consistent state before Py_DECREF() is invoked. For example, code to delete an object from a list should copy a reference to the deleted object in a temporary variable, update the list data structure, and then call Py_DECREF() for the temporary variable.

釋放o的strong reference,將它標記為不再被使用。

當物件的最後一個strong reference被釋放,也就是其reference count達到0後,該物體的deallocation function會自動被調用。

Py_XDECREF

Py_XDECREF

void Py_XDECREF(PyObject *o)
Similar to Py_DECREF(), but the object o can be NULL, in which case this has no effect. The same warning from Py_DECREF() applies here as well.

Py_DECREF類似,但是o可以為NULLoNULL時函數沒有作用。

Py_CLEAR

Py_CLEAR

void Py_CLEAR(PyObject *o)¶
Release a strong reference for object o. The object may be NULL, in which case the macro has no effect; otherwise the effect is the same as for Py_DECREF(), except that the argument is also set to NULL. The warning for Py_DECREF() does not apply with respect to the object passed because the macro carefully uses a temporary variable and sets the argument to NULL before releasing the reference.It is a good idea to use this macro whenever releasing a reference to an object that might be traversed during garbage collection.

釋放o的strong reference,作用與Py_DECREF相同。

o可以為NULLoNULL時函數沒有作用。

相关文章:

Python/C API - 模組,型別,Tuple,例外和引用計數

Python/C API - 模組&#xff0c;型別&#xff0c;Tuple&#xff0c;例外和引用計數 前言Python/C API - Common Object StructuresPyObjectPyMethodDefPyGetSetDef Python/C API - Module ObjectsPyModuleDefPyModule_CreatePyModule_AddObjectPyModule_AddObjectRef Initiali…...

人工智能轨道交通行业周刊-第59期(2023.9.4-9.10)

本期关键词&#xff1a;无锡智慧地铁、无人车站、钢轨打磨、混元大模型、开源大模型 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道世界…...

ASP.NET Core 中的 MVC架构

MVC 架构 MVC架构把 App 按照逻辑分成三层&#xff1a; Controllers&#xff0c;接收 http request&#xff0c;配合 model&#xff0c;通过http response 返回 view&#xff0c;尽量不做别的事Models, 负责业务逻辑&#xff0c;App 的状态&#xff0c;以及数据处理Views&…...

C# PSO 粒子群优化算法 遗传算法 随机算法 求解复杂方程的最大、最小值

复杂方程可以自己定义&#xff0c;以下是看别人的题目&#xff0c;然后自己来做 以下是计算结果 private void GetMinResult(out double resultX1, out double min){double x1, result;Random random1 new Random(DateTime.Now.Millisecond* DateTime.Now.Second);min 99999…...

网络协议从入门到底层原理学习(三)—— 路由

网络协议从入门到底层原理学习&#xff08;三&#xff09;—— 路由 1、简介 路由&#xff08;routing&#xff09;是指分组从源到目的地时&#xff0c;决定端到端路径的网络范围的进程 在不同网段之间转发数据&#xff0c;需要有路由器的支持 默认情况下&#xff0c;路由器…...

2023/9/6 -- C++/QT

一、输出流对象cout 1> 该对象是来自于ostream的类对象&#xff0c;功能上类似于printf函数 2> 该类对象本质上调用成员函数插入运算符重载函数 3> 输出数据时&#xff0c;无需使用格式控制符&#xff1a;%d、%c、%s。。。&#xff0c;直接输出即可 4> 换行使用…...

python爬虫,多线程与生产者消费者模式

使用队列完成生产者消费者模式使用类创建多线程提高爬虫速度 https://sc.chinaz.com/tupian/index.html https://sc.chinaz.com/tupian/index_2.html https://sc.chinaz.com/tupian/index_3.html from threading import Thread from queue import Queue import requests from b…...

WordPress 提示“此站点遇到了致命错误”的解决方法

WordPress 提示“此站点遇到了致命错误”的解决方法 WordPress 网站博客提示“此站点遇到了致命错误。”如何解决&#xff1f;今天老唐不幸遇到了这个问题&#xff0c;搜了一下解决方法&#xff0c;发现致命错误原因有很多&#xff0c;所以需要先打开 WordPress 的 WP_DEBUG 功…...

Vue3,Typescript中引用组件路径无法找到模块报错

是这么个事&#xff0c;我在vue3新创建的项目里&#xff0c;写了个组件叫headerIndex.vue&#xff0c;放到app.vue中import就会报错 路径肯定没写错&#xff0c;找到了解决方法&#xff0c;但是也没想明白为什么 解决方法如下 在vite-env.d.ts文件中加入 declare module &qu…...

科技成果鉴定之鉴定测试报告

鉴定测试 由于软件类科技成果的复杂、内部结构难以鉴别等特点&#xff0c;我们提供了软件类科技成果鉴定测试服务。软件类科技成果鉴定测试是依据其科研项目计划任务书或技术合同书&#xff0c;参照相应的国家标准对要申请鉴定的软件类科技成果进行的一种符合性测试&#xff0…...

NFTScan 浏览器正式版上线 2 周年!

NFTScan 成立于 2021 年 4 月份&#xff0c;总部位于香港。在 2021 年的 7 月份&#xff0c;NFTScan 团队对外发布了 NFTScan 浏览器公测版&#xff0c;并在同年的 9 月 4 号&#xff0c;对外发布了 NFTScan 浏览器正式版&#xff0c;同步启用了全球品牌域名&#xff1a;NFTSCA…...

为什么要使用Token

传统的session认证 我们知道&#xff0c;http协议是一种无状态的协议&#xff0c;这就意味着当用户向我们的应用提供了用户名和密码进行用户认证&#xff0c;那么在下一次登录的时候&#xff0c;用户还要再进行验证&#xff0c;因为根据http协议&#xff0c;浏览器并不知道是谁…...

前端面试的话术集锦第 8 篇:高频考点(JS性能优化 性能优化琐碎事)

这是记录前端面试的话术集锦第八篇博文——高频考点(JS性能优化 & 性能优化琐碎事),我会不断更新该博文。❗❗❗ 1. 从V8中看JS性能优化 注意:该知识点属于性能优化领域。 1.1 测试性能⼯具 Chrome已经提供了⼀个⼤⽽全的性能测试⼯具Audits。 点我们点击Audits后,可…...

【数据分析】Python:处理缺失值的常见方法

在数据分析和机器学习中&#xff0c;缺失值是一种常见的现象。在实际数据集中&#xff0c;某些变量的某些条目可能没有可用的值。处理缺失值是一个重要的数据预处理步骤。在本文中&#xff0c;我们将介绍如何在 Pandas 中处理缺失值。 我们将探讨以下内容&#xff1a; 什么是缺…...

“批量随机字母命名文件,轻松管理你的文件库“

你是否曾经遇到过文件命名混乱&#xff0c;难以管理的问题&#xff1f;为了解决这个问题&#xff0c;我们推出了一款全新的文件改名工具&#xff0c;它可以帮助你批量给文件名添加一个随机字母&#xff0c;让你的文件库更加有序、易于管理。 首先第一步&#xff0c;我们要进入…...

elasticsearch的数据聚合

聚合可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f; 这些手机的平均价格、最高价格、最低价格&#xff1f; 这些手机每月的销售情况如何&#xff1f; 实现这些统计功能的比数据库的sql要方便的多&#xff0c;而且…...

【网络编程·数据链路层】MAC帧/以太网协议/ARP协议/RARP协议

需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 一、MAC帧 1、IP地址和MAC地址的区别 2、MAC帧协议 3、MTU对IP协议的…...

算法:移除数组中的val的所有元素---双指针[2]

文章来源&#xff1a; https://blog.csdn.net/weixin_45630258/article/details/132689237 欢迎各位大佬指点、三连 1、题目&#xff1a; 给你一个数组 nums和一个值 val&#xff0c;你需要原地移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用…...

Python小知识 - Python爬虫进阶:如何克服反爬虫技术

Python爬虫进阶&#xff1a;如何克服反爬虫技术 爬虫是一种按照一定的规则&#xff0c;自动抓取网页信息的程序。爬虫也叫网页蜘蛛、蚂蚁、小水滴&#xff0c;是一种基于特定算法的自动化程序&#xff0c;能够按照一定的规则自动的抓取网页中的信息。爬虫程序的主要作用就是从一…...

SAP中的新旧事务码

SAP中的新旧事务码 SAP随着新版本的发布&#xff0c;我们知道sap已经更新了很多的程序和TCODE。sap提供了很多新的TCODE来替换旧的TCODE&#xff0c;新TCODE有很多的新特性和新功能。在这个这种情况下&#xff0c;很多旧TCODE就会被废弃。我们如何查找这个替换呢&#xff1f; …...

day3_C++

day3_C 思维导图用C的类完成数据结构 栈的相关操作用C的类完成数据结构 循环队列的相关操作 思维导图 用C的类完成数据结构 栈的相关操作 stack.h #ifndef STACK_H #define STACK_H#include <iostream> #include <cstring>using namespace std;typedef int datat…...

力扣题解(73. 矩阵置零),带注释

题目描述 链接:点我 题解 //法一 使用hashset记录有0的横纵坐标即可 class Solution {public void setZeroes(int[][] matrix) {HashSet<Integer> row new HashSet<Integer>();HashSet<Integer> col new HashSet<Integer>();for(int i 0;i <…...

SpringMVC应用

文章目录 一、常用注解二、参数传递2.1 基础类型String2.2 复杂类型2.3 RequestParam2.4.路径传参 PathVariable2.4 Json数据传参 RequestBody2.5 RequestHeader 三、方法返回值3.1 void3.2 Stringmodel3.3 ModelAndView 一、常用注解 SpringMVC是一个基于Java的Web框架&#…...

百度输入法全面升级,打造首个基于大模型的输入法原生应用

基于文心一言&#xff0c;百度输入法宣布全面升级&#xff0c;打造行业首个“基于大模型的输入法原生应用”&#xff0c;从“输入工具”全面转型为“AI创作工具”。 近日&#xff0c;百度文心一言正式向公众开放。基于文心一言&#xff0c;百度输入法宣布全面升级&#xff0c;打…...

如何解决GitHub 访问不了?小白教程

GitHub 是全球最大的代码开源平台&#xff0c;小伙伴们平时都喜欢在那里找一些优质的开源项目来学习&#xff0c;以提升自己的编程技能。 但是很多小白初探GitHub 发现访问不了&#xff0c;不能访问 通过一下方法绕过这堵墙&#xff0c;成功下载 GitHub 上的项目。过程非常简单…...

龙芯指令集LoongArch——学习笔记(1)

1 龙芯架构 PDF下载链接&#xff1a; https://www.loongson.cn/download/index 1.1 龙芯架构概述 龙芯架构具有 RISC 指令架构的典型特征。 它的指令长度固定且编码格式规整&#xff0c; 绝大多数指令只有两个源操作数和一个目的操作数&#xff0c; 采用 load/store 架构&…...

ubuntu 20.04 docker安装emqx 最新版本或指定版本

要在Ubuntu 20.04上使用Docker安装EMQX&#xff08;EMQ X Broker&#xff09;的4.4.3版本&#xff0c;您可以执行以下步骤&#xff1a; 1.更新系统包列表&#xff1a; sudo apt update2.安装Docker&#xff1a; sudo apt install docker.io3.启动Docker服务并设置其开机自启…...

软件测试/测试开发丨学会与 AI 对话,高效提升学习效率

点此获取更多相关资料 简介 ChatGPT 的主要优点之一是它能够理解和响应自然语言输入。在日常生活中&#xff0c;沟通本来就是很重要的一门课程&#xff0c;沟通的过程中表达越清晰&#xff0c;给到的信息越多&#xff0c;那么沟通就越顺畅。 和 ChatGPT 沟通也是同样的道理&…...

CEF内核和高级爬虫知识

(转)关于MFC中如何使用CEF内核&#xff08;CEF初解析&#xff09; Python GUI: cefpython3的简单分析和应用 cefpython3&#xff1a;一款强大的Python库 开始大多数抓取尝试可以从几乎一行代码开始&#xff1a; fun main() PulsarContexts.createSession().scrapeOutPages(&q…...

视频集中存储/云存储/磁盘阵列EasyCVR平台分组批量绑定/取消设备功能详解

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台视频能力丰富灵活&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理平台EasyCVR既具备传…...

深圳专业做网站的公司/北京seo代理公司

什么&#xff1f;你还不会写JQuery 插件转载于:https://www.cnblogs.com/lbonet/p/7274968.html...

架设网站 自己购买服务器/宁波seo怎么做推广渠道

Linux下搭建Apache服务器&#xff08;完整版&#xff09; 什么是Apache&#xff1f; Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似&#xff0c;同样鼓励代码共享和尊重原作者的著作权&#xff0c;同样允许代码修改&#xff0c;再发布(作为开源或商业…...

如何搭建一个网站步骤/什么是引流推广

1.jquerymobile的引用 略 2.引用后&#xff0c;页面跳转后&#xff0c;自己的js无法执行&#xff0c;需刷新。解决&#xff1a;在上个页面链接跳转出加&#xff1a;data-ajax"false" 3.data-prefetch"false"的使用转载于:https://www.cnblogs.com/wuchao/a…...

长沙哪个公司做网站/百度投诉电话人工客服24小时

1、基础设施即服务 (IaaS) 基础设施即服务有时缩写为 IaaS&#xff0c;包含云 IT 的基本构建块&#xff0c;通常提供对联网功能、计算机&#xff08;虚拟或专用硬件&#xff09;以及数据存储空间的访问。基础设施即服务提供最高等级的灵活性和对 IT 资源的管理控制&#xff0c;…...

网站建设公司西安/上海搜索引擎关键词优化

堆和栈的区别 一个由C/C编译的程序占用的内存分为以下几个部分 1、栈区&#xff08;stack&#xff09;— 由编译器自动分配释放 &#xff0c;存放函数的参数值&#xff0c;局部变量的值等。其 操作方式类似于数据结构中的栈。 2、堆区&#xff08;heap&#xff09; — 一般由程…...

福建网站模板/永久免费客服系统

/*这题的思路让我觉得很巧妙&#xff0c;所以...虽然小白书 P175 &#xff0c;已经有详细到能看懂的解释了&#xff0c;但我还是用自己的话&#xff0c;把书上的解析复述一遍:简化&#xff1a;先判断解的存在性&#xff0c;有解再找解类比&#xff1a;可将敌人类比为圆&#x…...