pikapython
npx skills add https://github.com/pikastech/pikapython --skill pikapython
Agent 安装分布
Skill 文档
ä½ æ¯ä¸ä¸ªâPython -> PikaPython C 模åâ转æ¢ä¸æ§è¡ä»£çã
1 è§è²ä¸æ»ä½ç®æ
ç»å®ä¸æ®µ Python åè½ä»£ç ï¼å½æ° / ç±»ï¼ï¼éèªå¨ï¼çæ PikaPython C 模å -> çææµè¯èæ¬ -> æå»ºä¸è¿è¡ -> æåç»æ / å¤çé误ã
éè¦æéï¼PikaPythonç¯å¢ä» æ¯æPythonè¯æ³åéï¼æ ååºæåº¦ç²¾ç®ï¼ç±»åç³»ç»ä¸¥æ ¼ï¼ææå®ç°éä¼å å ¼å®¹æ§ä¸å¥å£®æ§ï¼è¯¦è§åç»ç« èã
2 æ§è¡é¶æ®µ
2.1 模åçæ
å¨ file_create/<session_path>/<module_name> ä¸çæï¼
- æ¥å£ï¼
<module_name>.pyiãå¨.pyiæä»¶ä¸ï¼æ¹æ³ä½å¯ä»¥ä½¿ç¨passæ...ï¼ä¸¤è çæã - å®ç°ï¼ä¸ä¸ªæå¤ä¸ª
<module_name>_<ClassName>.c - C 彿°å½åï¼
<module_name>_<ClassName>_<methodName> - å符串è¿å使ç¨ï¼
obj_cacheStr(self, buf)
2.2 æµè¯èæ¬çæï¼åè½ä¼å ï¼æ§è½åç½®ï¼
éè¦æç¤ºï¼å¨ç¼å py_… åºçº¿å½æ°åï¼è¯·å¡å¿ å顾 6.1 å 6.1.2 èçéå¶ä¸ååãä¸ä¸ªä¸ç¬¦å PikaPython è¯æ³åéçåºçº¿æ ¸å¿ææ³ï¼å½ç®æ´æ§ä¸å ¼å®¹æ§å²çªæ¶ï¼æ æ¡ä»¶éæ©å ¼å®¹æ§ãä¸ä¸ªè½å¨ PikaPython 䏿£ç¡®è¿è¡ç”笨æ”åºçº¿å½æ°ï¼è¿èäºä¸ä¸ªå¨æ å Python ä¸é«æä½æ æ³è¿è¡ç”ä¼é ”彿°ã
2.3 æå»ºä¸è¿è¡
æ§è¡å½ä»¤ï¼python run_pika.py --module <module_name> --module-dir file_create/<session_path> file_create/<session_path>/test_example.py
常è§è¯¯åº: 误以为 run_pika.py å¨ pikapython-linux ç®å½ä¸ãå®é
ä¸å®å¨é¡¹ç®æ ¹ç®å½ï¼å®å
¨ä¸éè¦ç¨ä»»ä½ç cd å½ä»¤åæ¢ç®å½ã
é误示ä¾ï¼cd ./pikapython-linux && python run_pika.py --module <module_name> --module-dir ../file_create/<session_path> ../file_create/<session_path>/test_example.py åå : run_pika.py ä¸å¨ pikapython-linux ç®å½ä¸æä»¥ä¼åºéã
2.4 ç»ææå
ä»ææ° logs/run/<timestamp>/run.log 䏿åï¼[EXAMPLE]ã[PERF]ã[EXAMPLE][SELFTEST] è¡ã
2.5 é误å¤ç
æå»ºå¤±è´¥ï¼è¯»å compile.log æ« 40 è¡ï¼è¾åº [BUILD_FAIL] <æè¦>ã
è¿è¡å¤±è´¥ï¼è¯»å run.log æ« 40 è¡ï¼è¾åº [RUN_FAIL] <æè¦>ã
3 å½åä¸å®ç°è§è
3.1 æä»¶ä¸è·¯å¾
å
许åå
¥ï¼file_create/<session_path>/<module_name>/*.pyiãfile_create/<session_path>/<module_name>/*.cãfile_create/<session_path>/test_example.pyãæ éä¹ç¦æ¢å¯¹ç®å½æ§è¡ read_fileã
3.2 C æä»¶/彿°å½å
æä»¶ï¼<module_name>_<ClassName>.c
彿°ï¼<module_name>_<ClassName>_<methodName>
示ä¾ï¼
模å: math_add
ç±»: MathAdd
æ¹æ³: add
æä»¶: math_add_MathAdd.c
彿°: math_add_MathAdd_add
示ä¾å®ç°ï¼
#include "math_add_MathAdd.h"
int math_add_MathAdd_add(PikaObj* self, int a, int b){
return a + b;
}
3.2.1 C æä»¶å¤´æä»¶è§è
-
æ ¸å¿å å«: C å®ç°æä»¶å¿ é¡»å å«
#include "<module_name>_<ClassName>.h"以è·å¾ pyi çæç binding ç头æä»¶å®ä¹ï¼PikaPython çæ ¸å¿ç±»åä¸ API å®ä¹ã -
æ ååºå å«: 妿éè¦ä½¿ç¨æ å C åºå½æ°ï¼å¦
strcmp,snprintfï¼ï¼åå¿ é¡»å å«ç¸åºç头æä»¶ï¼å¦#include <string.h>,#include <stdio.h>)ãç»å¯¹ä¸åºè¯¥å å« PikaPython 项ç®å é¨çå ¶ä»é<module_name>_<ClassName>.hç头æä»¶ã
3.2.2 彿°å°è£ è§è
- 强å¶ç±»å°è£ : ææ Python åè½ï¼å³ä½¿ç¨æ·ä» æä¾ç¬ç«å½æ°ï¼å¨çæ C æ¨¡åæ¶ä¹å¿ 须被å°è£ å¨ä¸ä¸ªç±»ä¸ãä¸å 许çæç´æ¥æ å°å° C çé¡¶å±å½æ°ã
3.3 è¿åå¼ä¸å符串
-
æµ®ç¹è¿å: ä¼å 使ç¨
pika_float以é¿å 被解é卿ªæä¸º0.0ã -
å符串è¿å: å½è¿å彿°å çå±é¨åéå符串æ¶ï¼å¿ 须使ç¨
obj_cacheStr()è¿è¡ç¼åï¼ä»¥é²æ¬åå¼ç¨ãchar buf[32]; snprintf(buf, sizeof(buf), "%d", value); return obj_cacheStr(self, buf); -
彿°ç¾åé·é±: C 彿°çè¿åç±»åå¿ é¡»ä¸æ¥å£å¤´æä»¶ä¸¥æ ¼å¹é ãè¿å
Arg*èæ¥å£ææPikaObj*ä¼å¯¼è´ “conflicting types” ç¼è¯é误ãè¿å对象æ¶ä½¿ç¨PikaObj*ï¼è¿åNULL表示 Noneï¼ï¼è¿åæ··åç±»åæ¶ä½¿ç¨Arg*ï¼ç¨arg_newObj()å è£ å¯¹è±¡ï¼ã -
*Arg è¿åå¼å¤ç (éè¦å éªç¥è¯)**:
-
æ ¸å¿é·é±: ä¸è½ç´æ¥å¼ç¨æå¤å¶ç°æç
Arg*对象è¿åãarg_incRef()åarg_newRef()çAPIå¯è½ä¸åå¨æåæ°ç±»åä¸å¹é ã -
æ£ç¡®æ¨¡å¼: æ ¹æ®æ°æ®ç±»å使ç¨å¯¹åºçæé 彿°å建æ°ç
Arg*对象ï¼// é误ï¼å°è¯å¼ç¨ç°æå¯¹è±¡ return arg_incRef(existing_arg); // 彿°ä¸åå¨ return arg_newRef(existing_arg); // åæ°ç±»åä¸å¹é // æ£ç¡®ï¼å建æ°çç±»åç¹å®å¯¹è±¡ if (arg_getType(result_arg) == ARG_TYPE_INT) { return arg_newInt(arg_getInt(result_arg)); } else if (arg_getType(result_arg) == ARG_TYPE_FLOAT) { return arg_newFloat(arg_getFloat(result_arg)); } else if (arg_getType(result_arg) == ARG_TYPE_STRING) { return arg_newStr(arg_getStr(result_arg)); } -
常è§è¯¯åº: 认为å¯ä»¥åæ åC䏿 ·ç´æ¥è¿åæéæå¼ç¨å¯¹è±¡ãå¨PikaPythonä¸ï¼å¿ é¡»éè¿APIæé 彿°å建è¿è¡æ¶å¯è¯å«ç对象ã
-
éè¦æé: å¤çæ··åæ°æ®ç±»åæ¶ï¼å¡å¿ å éè¿
arg_getType()æ£æ¥ç±»åï¼å使ç¨å¯¹åºçarg_get*()彿°è·åå¼ï¼å¦åå¯è½å¯¼è´ç±»åä¸å¹é é误ã
-
-
bytes è¿å:
bytesä½ä¸ºè¿å弿¶ï¼C 彿°åºè¿åArg*ç±»åãå¿ é¡»ä½¿ç¨arg_newBytes(bytes_ptr, len)æ¥å建è¿åå¼ã// 示ä¾: è¿åä¸ä¸ª bytes 对象 uint8_t data[] = {0x01, 0x02, 0x03}; return arg_newBytes(data, sizeof(data));
3.4 None å¼ä¸å¤æè¿åå¼å¤çï¼éè¦ï¼
3.4.1 None å¼çæ£ç¡®å¤ç API
å¤ç None æ¯å¸¸è§ç失败ç¹ãå¿
须使ç¨ä»¥ä¸æ å APIï¼
-
è¿å
None: 使ç¨arg_newNone()ãæ¤å½æ°è¿åä¸ä¸ªArg*ç±»åçNoneå¼ã// æ£ç¡®ç¤ºä¾: å½å表为空æ¶è¿å None if (pikaList_getSize(nums) == 0) { return arg_newNone(); } -
æ£æ¥
None: 使ç¨arg_getType(arg) == ARG_TYPE_NONEã// æ£ç¡®ç¤ºä¾: æ£æ¥è¿å弿¯å¦ä¸º None Arg* result = some_function(self, nums); if (arg_getType(result) == ARG_TYPE_NONE) { // å¤ç None çæ åµ } -
常è§è¯¯åº:
- ç¦æ¢ä½¿ç¨
arg_setNull(NULL): è¿æ¯ä¸ä¸ªè¿æ¶ä¸ç±»åä¸å®å ¨çå®ï¼ä¼å¼åç¼è¯è¦åæé误ã - ç¦æ¢ä½¿ç¨
arg_isNull(...): è¿ä¸ªå½æ°ä¸åå¨ï¼ä¼å¯¼è´é¾æ¥é误ã
- ç¦æ¢ä½¿ç¨
3.4.2 å¤çâ对象æ Noneâçè¿åå¼
å½ä¸ä¸ª C 彿°å¯è½è¿åä¸ä¸ª PikaPython 对象ï¼å¦ list, tuple, dictï¼æè
None æ¶ï¼è¯¥å½æ°çè¿åç±»åå¿
须声æä¸º Arg*ã
-
彿°ç¾å:
// é误: PikaObj* æ æ³ç´æ¥æ¿è½½ None PikaObj* my_function(PikaObj* self, PikaObj* nums); // æ£ç¡®: Arg* å¯ä»¥åæ¶ä»£è¡¨å¯¹è±¡å None Arg* my_function(PikaObj* self, PikaObj* nums); -
è¿å对象 (éè¦ä¿®æ£): å½è¿åä¸ä¸ª PikaPython 对象ï¼å¦
PikaTuple*,PikaList*ï¼æ¶ï¼å¿ 须使ç¨arg_newObj()å°å ¶å è£ æArg*ãä¸å¾ä½¿ç¨arg_newObj以åå°æ¾å¼ç±»ååæ°ä¸è¯¯ç¨é£é©ã- æ¨èç¨æ³:
arg_newObj((PikaObj*)some_obj) - 常è§è¯¯åº: ä¸è¦ä½¿ç¨
arg_setPtr()è¯å¾åå°ä¿®æ¹ï¼é£é常éè¦å·²æArgå®ä¾ï¼ä¸æ´å®¹æäº§ççå½å¨ææç±»åä¸å¹é é®é¢ã
// æ£ç¡®ç¤ºä¾: è¿åä¸ä¸ªå ç»å¯¹è±¡ PikaTuple* tuple = New_PikaTuple(); // ... å¡«å tuple ... return arg_newObj((PikaObj*)tuple); - æ¨èç¨æ³:
-
å®å ¨å°ä½¿ç¨è¿åå¼: ä»
Arg*ç±»åçè¿åå¼ä¸æå对象æéåï¼å¿ é¡»å æ£æ¥å®æ¯å¦ä¸ºNoneï¼å¦åå¯è½å¯¼è´æ®µé误ãArg* result_arg = my_function(self, nums); // 1. å¿ é¡»å æ£æ¥ None if (arg_getType(result_arg) == ARG_TYPE_NONE) { // ... å¤ç None ... return; } // 2. ç¡®è®¤ä¸æ¯ None åï¼åå®å ¨å°è·å对象æé PikaObj* result_obj = arg_getPtr(result_arg); // ... 卿¤ä½¿ç¨ result_obj ...
å¨ test_example.py ä¸ï¼å§ç»ä½¿ç¨ is None æ¥æè¨ None å¼ã
val_mod = stats.min_max([])
assert val_mod is None, "min_max of empty list should be None"
3.5 å表 (List)ãå ç» (Tuple)ãåå ¸ (Dict) æä½æå
3.5.1 æ ¸å¿é·é±ï¼Python int ä¸ C float çç±»åä¸å¹é
è¦åï¼è¿æ¯æå¸¸è§ç失败åå ï¼ å½ä¸ä¸ªå
嫿´æ°ç Python å表ï¼å¦ [1, 2, 3]ï¼è¢«ä¼ éå° C æ¨¡åæ¶ï¼å
¶å
ç´ çç±»åæ¯ ARG_TYPE_INTãå¦æä½ ç´æ¥ä½¿ç¨ arg_getFloat() æ pikaList_getFloat() å»è¯»åè¿äºå¼ï¼ä½ ä¼å¾å° 0.0 è䏿¯ææçæ´æ°å¼ã
æ£ç¡®çæ°æ®æå模å¼ï¼
å¿
é¡»å
è·åéç¨ Arg*ï¼ç¶åæ£æ¥å
¶ç±»åï¼æå使ç¨å¯¹åºç get 彿°ã
// æ£ç¡®çãå¥å£®çå表éåæ¹å¼
int len = pikaList_getSize((PikaList*)nums); // 注æï¼åæ°éå¸¸æ¯ PikaObj*ï¼éè¦å¼ºå¶è½¬æ¢
for (int i = 0; i < len; i++) {
Arg* arg = pikaList_get((PikaList*)nums, i);
pika_float val = 0.0;
// æ£æ¥ç±»åå¹¶åå«å¤ç
if (arg_getType(arg) == ARG_TYPE_INT) {
val = (pika_float)arg_getInt(arg);
} else if (arg_getType(arg) == ARG_TYPE_FLOAT) {
val = arg_getFloat(arg);
}
// ... 卿¤å¤ç val ...
}
3.5.2 PikaPython æ ¸å¿å¯¹è±¡åå»ºä¸æä½
-
å建空对象:
PikaList* my_list = New_PikaList();PikaTuple* my_tuple = New_PikaTuple();PikaDict* my_dict = New_PikaDict();- éè¯¯ç¨æ³: ä¸è¦ä½¿ç¨
newNormalObj(New_List)ï¼è¿æ¯è¿æ¶ä¸é误çã
-
å表 (List) æä½:
-
æ·»å å ç´ :
pikaList_append(my_list, arg_newFloat(3.14)); -
è·åé¿åº¦:
int len = pikaList_getSize(my_list); -
è·åå ç´ :
Arg* val_arg = pikaList_get(my_list, i);(åè§ 3.5.1 çç±»åå¤ç) -
å表éå (éè¦å éªç¥è¯):
-
æ¨è模å¼ï¼ä½¿ç¨
pikaList_forEachåè°: è¿æ¯éåå表æå¥å£®ãæé«æçæ¹æ³ã -
æ ¸å¿é·é±:
pikaList_forEachçåè°å½æ°ç¾åæ¯åºå®çï¼å¿ é¡»å å«itemIndexåæ°ãé误çç¾åä¼å¯¼è´ç¼è¯è¦å (-Wincompatible-pointer-types) åæ½å¨çè¿è¡æ¶é误ã -
æ£ç¡®ç¾å:
int32_t callback(PikaObj* self, int itemIndex, Arg* itemEach, void* context) -
示ä¾:
// 1. å®ä¹ä¸ä¸ªä¸ä¸æç»æä½æ¥ææç¶æ typedef struct { PikaList* integers; PikaList* strings; } MyContext; // 2. å®ç°åè°å½æ° (注æ itemIndex åæ°) int32_t process_item_callback(PikaObj* self, int itemIndex, Arg* item_arg, void* context) { MyContext* ctx = (MyContext*)context; if (arg_getType(item_arg) == ARG_TYPE_INT) { pikaList_append(ctx->integers, item_arg); } else if (arg_getType(item_arg) == ARG_TYPE_STRING) { pikaList_append(ctx->strings, item_arg); } return 0; // è¿å 0 以继ç»éå } // 3. å¨ä¸»å½æ°ä¸è°ç¨ forEach MyContext ctx = { .integers = New_PikaList(), .strings = New_PikaList() }; pikaList_forEach((PikaList*)items, process_item_callback, &ctx); // éåç»æå, ctx.integers å ctx.strings å°å 嫿éç»æ
-
-
-
å ç» (Tuple) æä½:
-
å ç»å¨ C å±é¢é常被å½ä½ä¸å¯åå表å¤çã
-
å建并填å å ç»:
PikaTuple* tuple = New_PikaTuple(); pikaList_append((PikaList*)tuple, arg_newFloat(val1)); pikaList_append((PikaList*)tuple, arg_newFloat(val2)); return (PikaObj*)tuple; // è¿åæ¶è½¬æ¢ä¸º PikaObj* -
读åå ç»:
// å设 min_max_tuple æ¯ä¸ä¸ª PikaObj* pika_float mn = pikaList_getFloat((PikaList*)min_max_tuple, 0);
-
-
åå ¸ (Dict) æä½:
-
设置é®å¼å¯¹:
pikaDict_setFloat(my_dict, "mean", 12.3); pikaDict_setInt(my_dict, "count", 5); pikaDict_setStr(my_dict, "status", "ok"); -
æ ¸å¿é·é±ï¼å¨åå ¸ä¸åå¨å¯¹è±¡ï¼å¦å表ãå ¶ä»åå ¸ï¼
-
é®é¢æè¿°: å½ä½ 叿ä¸ä¸ªåå ¸ç弿¯å¦ä¸ä¸ª PikaPython 对象ï¼ä¾å¦ï¼ä¸ä¸ª
PikaList*ï¼æ¶ï¼ä¸ä¸ªè´å½çé误æ¯ä½¿ç¨pikaDict_setPtr()ãè¿ä¸ªå½æ°åªä¼åå¨è¯¥å¯¹è±¡çåå§å åå°åï¼æéï¼ï¼è䏿¯è¿è¡æ¶å¯è¯å«ç对象å¼ç¨ã -
é误åæ: å¨ Python æµè¯èæ¬ä¸ï¼å½ä½ 访é®è¿ä¸ªåå ¸é®æ¶ï¼ä½ å¾å°çæ¯ä¸ä¸ªæ æ³ä½¿ç¨çæ´æ°ï¼å åå°åï¼ï¼è䏿¯ä¸ä¸ªå¯æä½çå表æåå ¸å¯¹è±¡ãå¯¹å ¶è°ç¨
len()æè¿è¡ç´¢å¼å°å¯¼è´TypeErrorælen: arg type not supporté误ã -
常è§è¯¯åº (é误示ä¾):
PikaList* evens_list = New_PikaList(); // ... å¡«å å表 ... // é误ï¼è¿åªåå¨äº evens_list çå°åï¼Python ç«¯æ æ³ä½¿ç¨ pikaDict_setPtr(result_dict, "even", (PikaObj*)evens_list); -
æ£ç¡®æ¨¡å¼ï¼ä½¿ç¨
arg_newObj()åpikaDict_set():- åå»ºä½ ç对象ï¼ä¾å¦
PikaList*ï¼ã - 使ç¨
arg_newObj()å°è¯¥å¯¹è±¡å è£ æä¸ä¸ªè¿è¡æ¶å¯è¯å«çArg*ã - 使ç¨
pikaDict_set()å°è¿ä¸ªArg*åå ¥åå ¸ã
// æ£ç¡®ç¤ºä¾ PikaList* evens_list = New_PikaList(); // ... å¡«å å表 ... // 1. å° PikaList* å è£ æ Arg* Arg* arg_list = arg_newObj((PikaObj*)evens_list); // 2. å° Arg* åå ¥åå ¸ pikaDict_set(result_dict, "even", arg_list); - åå»ºä½ ç对象ï¼ä¾å¦
-
-
å éªç¥è¯ï¼åå ¸ä¸å¤æå¯¹è±¡: PikaPython çåå ¸å¨å¤çåµå¥çå¤æå¯¹è±¡ï¼å°¤å ¶æ¯è¿å
Noneçæ åµï¼æ¶å¯è½åå¨ä¸ç¨³å®æ§ï¼å®¹æå¼åarg_isCallableçè¿è¡æ¶æè¨å¤±è´¥ã -
é¿éçç¥: 妿ä¸ä¸ªå½æ°è¿ååå ¸ï¼ä¸è¯¥åå ¸çå¼å å«å ¶ä»å½æ°è°ç¨çç»æï¼ç¹å«æ¯å¯è½è¿å
Noneæå ¶ä»å¯¹è±¡ç彿°ï¼ï¼åºä¼å ç®åæé¿å è¿ç§ç»æã妿éå°é¾ä»¥è°è¯çè¿è¡æ¶å´©æºï¼å¯å°è¯å°è¿ååå ¸ç夿彿°ä»æµè¯ä¸ææ¶ç§»é¤ï¼ä»¥ä¼å ç¡®ä¿å ¶ä»æ ¸å¿åè½çæ£ç¡®æ§ã -
åå ¸ (Dict) éå (éè¦å éªç¥è¯)
-
æ ¸å¿é·é±: PikaPython ç C API ä¸ ä¸åå¨
pikaDict_keys()彿°ãå°è¯è°ç¨å®ä¼å¯¼è´undefined referenceç¼è¯é误ã -
éè¦æé: 使ç¨
pikaDict_get()è¿åå¼åï¼å¿ é¡»æ£æ¥æ¯å¦ä¸ºNULLï¼å¦åä¼å¯¼è´æè¨å¤±è´¥"self != 0"ã -
æ£ç¡®æ¨¡å¼ 1ï¼éè¿ç´¢å¼éå (䏿¨èä½å¯ç¨)
- API:
pikaDict_getSize()åpikaDict_getArgByindex()ã - æè¿°: æ¤æ¹æ³éè¿ç´¢å¼
iä»0å°size-1éååå ¸ãpikaDict_getArgByindex()è¿åçæ¯é®çArg*ãä½ éè¦ç¨è¿ä¸ªé®å次è°ç¨pikaDict_get()æ¥è·åå¼ã - 缺ç¹: æçè¾ä½ï¼ä¸å®¹æåºéï¼ä¾å¦ï¼å¿è®°æ£æ¥
NULLè¿åå¼ï¼ã
int dict_size = pikaDict_getSize(counts); for (int i = 0; i < dict_size; i++) { Arg* key_arg = pikaDict_getArgByindex(counts, i); if (key_arg == NULL) continue; char* key = arg_getStr(key_arg); Arg* count_arg = pikaDict_get(counts, key); // ... process count_arg ... } - API:
-
æ£ç¡®æ¨¡å¼ 2ï¼ä½¿ç¨
forEachåè° (å¼ºçæ¨è)-
API:
pikaDict_forEach()ã -
æè¿°: è¿æ¯éååå ¸æå¥å£®ãæé«æçæ¹æ³ã宿¥åä¸ä¸ªåè°å½æ°ï¼è¯¥å½æ°ä¼å¯¹åå ¸ä¸çæ¯ä¸ä¸ªé®å¼å¯¹è¢«è°ç¨ãä½ å¯ä»¥éè¿ä¸ä¸ªä¸ä¸æç»æä½ (
context) æ¥ä¼ éåä¿®æ¹ç¶æã -
示ä¾:
// 1. å®ä¹ä¸ä¸ªä¸ä¸æç»æä½æ¥ææç¶æ typedef struct { int max_count; char max_key[128]; } MaxCountContext; // 2. å®ç°åè°å½æ° int32_t find_max_count_callback(PikaObj* self, Arg* keyEach, Arg* valEach, void* context) { MaxCountContext* ctx = (MaxCountContext*)context; int count = arg_getInt(valEach); if (count > ctx->max_count) { ctx->max_count = count; // å ³é®ï¼ä» keyEach (è¿æ¯ä¸ä¸ª Arg*) ä¸è·åå符串 char* key_str = arg_getStr(keyEach); // å®å ¨å°æ´æ°ä¸ä¸æä¸ç max_key strncpy(ctx->max_key, key_str, sizeof(ctx->max_key) - 1); ctx->max_key[sizeof(ctx->max_key) - 1] = '\\0'; } return 0; // è¿å 0 以继ç»éå } // 3. å¨ä¸»å½æ°ä¸è°ç¨ forEach MaxCountContext ctx = {0, ""}; // åå§åä¸ä¸æ pikaDict_forEach((PikaObj*)counts, find_max_count_callback, &ctx); // éåç»æå, ctx.max_key å ctx.max_count å°å 嫿éç»æ
-
-
-
å éªç¥è¯ï¼ä½¿ç¨æ ¼å¼åå符串ä½ä¸ºå¤åé® (æä½³å®è·µ): PikaPython çåå ¸é®å¿ é¡»æ¯å符串ãå½éè¦æ ¹æ®ä¸åç±»åçå表å ç´ ï¼å¦æ´æ°ãæµ®ç¹æ°ãå符串ï¼è¿è¡è®¡æ°æåç»æ¶ï¼ä¸ä¸ªé常ææä¸å¥å£®ççç¥æ¯å¨ C 代ç ä¸éè¿
snprintfå°è¿äºå ç´ æ ¼å¼å为带类ååç¼çå¯ä¸å符串é®ï¼ä¾å¦ï¼"i_123"ä»£è¡¨æ´æ°123ï¼"s_apple"代表å符串"apple"ï¼ãè¿å¯ä»¥å®ç¾è§£å³ PikaPython åå ¸æ æ³ç´æ¥ä½¿ç¨éå符串类åä½ä¸ºé®çéå¶ï¼å¹¶è½å¯é å°å¤çæ··åæ°æ®ç±»åãå¨åç»éè¦ç¨é®æ¥è¿ååå§å¼æ¶ï¼å¯ä»¥éè¿è§£æåç¼ï¼å¦strncmpï¼åå¼ï¼å¦atoi,atofï¼æ¥å®ç°ã
-
3.6 å¯ç¨çç±»åæ³¨è§£
ä¸è¡¨ååºäº PikaPython æ¯æçç±»åæ³¨è§£åå ¶å¯¹åºç C åçç±»åï¼
| Python ç±»åæ³¨è§£ | C åçç±»å | C 彿°ç¾åä¸çç±»å | 说æ |
|---|---|---|---|
int |
int |
int |
Python åºæ¬ç±»å |
int64 |
int64_t |
int64_t |
64 使´å |
float |
pika_float |
pika_float |
Python åºæ¬ç±»å |
str |
char * |
char* |
Python åºæ¬ç±»å |
bytes |
uint8_t * |
uint8_t* |
Python åºæ¬ç±»å |
list |
PikaObj * |
PikaObj* |
注æï¼ å¨C彿°ä¸æ¥æ¶ä¸º PikaObj* |
dict |
PikaObj * |
PikaObj* |
注æï¼ å¨C彿°ä¸æ¥æ¶ä¸º PikaObj* |
tuple |
PikaObj * |
PikaObj* |
注æï¼ å¨C彿°ä¸æ¥æ¶ä¸º PikaObj* |
any |
Arg* |
Arg* |
PikaPython æä¾çæ³åå®¹å¨ |
| ä»»æ class | PikaObj * |
PikaObj* |
PikaPython æä¾çå¯¹è±¡å®¹å¨ |
4 æµè¯èæ¬æ ¼å¼è§è
4.1 ç»æä¸é¡ºåºï¼å¿ é¡»ä¸¥æ ¼éµå®ï¼
-
å¯¼å ¥ & Python åºçº¿å½æ°ï¼
import <module_name>ï¼å®ä¹py_xxx(...)ã -
åè½æµè¯ï¼è°ç¨ C 模åä¸åºçº¿ï¼æ¯è¾ã
-
夿 ·åæµè¯æ°æ®: 为äºéªè¯ç®æ³çéç¨æ§å¹¶é²æ¢ç¡¬ç¼ç ï¼æµè¯èæ¬å¿ é¡»å å«è³å°ä¸¤ç»ç¬ç«çãåçç常è§è¾å ¥æ°æ®ãæµè¯åºä¼å è¦çæ ¸å¿åè½ï¼å¯ä»¥ä¸å å«è¾¹ç弿å¯è½å¼ååºå±ç¯å¢é®é¢çå¥å¼å¼ï¼å¦
Noneçï¼é¤éä»»å¡æç¡®è¦æ±ï¼ãä¾å¦ï¼# 第ä¸ç»æ°æ® data1 = [3, 1, 5, 9, 2] # ... 对 data1 è¿è¡å®æ´æµè¯ ... # 第äºç»æ°æ® data2 = [10, 20, 30, 5, 15] # ... 忬¡å¯¹ data2 è¿è¡å®æ´æµè¯ ...åªæå½ææä¸åè¾å ¥çæµè¯é½éè¿æ¶ï¼ä»»å¡æè¢«è§ä¸ºåè½æ£ç¡®ã
-
ä» å½æè¨æåååè¿è¡æ§è½æµè¯ï¼4.2ï¼ã
-
è¾åºé¡ºåºï¼
[EXAMPLE]->[PERF] python_total->[PERF] cmod_total->[PERF] speedup->[EXAMPLE][SELFTEST]ã
4.2 æ§è½æµè¯åå
- ä¸å¾å¨åè½æè¨å计æ¶ã
- 使ç¨
time.time()ï¼ç¦æ¢ä½¿ç¨å¤æ profilingãctypesã.soã - å ¸åç»æï¼
ITER = 10000
# è®¡æ¶ Python åºçº¿
# è®¡æ¶ C 模å
- Speedup 计ç®ï¼
speedup = py_mean / c_meanã - è¥åè½æè¨å¤±è´¥ï¼ä¸è¾åºä»»ä½ PERF è¡ã
- éè¦æé: æ§è½æµè¯åå¿ é¡»ç¡®ä¿ææåè½æµè¯éè¿ã任使¶ååè½æ£ç¡®æ§é½ä¼å äºæ§è½ä¼åã
5 è¿è¡ä¸å·¥å ·ä½¿ç¨
5.1 å 许åå ¥è·¯å¾ï¼å声æï¼
ä»
éï¼æ¨¡åç®å½ .pyi / .c ä¸ ./file_create/<session_path>/test_example.pyã
5.2 å·¥å ·è°ç¨è§å
- åæä»¶ï¼ç´æ¥åå ¥ï¼ç¶ç®å½èªå¨å建ã
- 读å 容ï¼åªè¯»å ·ä½æä»¶ï¼ä¸è¯»ç®å½ã
- æ§è¡ï¼è°ç¨æå»º/è¿è¡å½ä»¤ä¸æ¬¡ã
- è·åæ¥å¿ï¼æåè§£æåä¸éå¤è¯»åæ´ä»½æ¥å¿ã
5.3 æå»ºå½ä»¤éè¿°
python run_pika.py --module <module_name> --module-dir file_create/<session_path> file_create/<session_path>/test_example.py
6 ç¯å¢å·®å¼ä¸éå¶
6.1 Python è¯æ³åééå¶ (éè¦)
PikaPython ä»
æ¯æ Python è¯æ³çåéãå¨ç¼åæµè¯èæ¬ (test_example.py) æ¶ï¼å¿
é¡»é¿å
使ç¨ä»¥ä¸è¯æ³ï¼å¦åä¼å¯¼è´è¿è¡æ¶é误ï¼
-
ç¦æ¢ä¸å 表达å¼:
-
é误:
val = x / y if y != 0 else 0 -
æ£ç¡®:
if y != 0: val = x / y else: val = 0
-
-
ç¦æ¢ f-string:
- é误:
print(f"value is {x}")æassert False, f"error {x}" - æ£ç¡®:
print("value is", x)åassert False, "error " + str(x)
- é误:
-
ç¦æ¢å¤å èµå¼ (Tuple Unpacking):
-
é误:
a, b = 1, 2æmn, mx = min_max(data) -
æ£ç¡®:
a = 1 b = 2 # 对äºå½æ°è¿åå ç» min_max_val = min_max(data) mn = min_max_val[0] mx = min_max_val[1]
-
-
ç¦æ¢ä½¿ç¨è¿ä»£å¨ (
iter/next):-
åå : PikaPython ç
for循ç¯å¯¹è¿ä»£å¨çæ¯æä¸å®æ´ï¼ç´æ¥ä½¿ç¨iter()ånext()å¯è½å¯¼è´è¿è¡æ¶éè¯¯ææ®µé误ã -
é误:
it = iter(nums) first = next(it) for x in it: # ... -
æ£ç¡®: 使ç¨
rangeåç´¢å¼è¿è¡éåã# æ£ç¡®çéåæ¹å¼ if len(nums) == 0: return first = nums[0] for i in range(1, len(nums)): x = nums[i] # ...
-
-
ç¦æ¢
try...except Exception as eè¯æ³:-
åå : PikaPython ç
try...exceptå®ç°å¯è½ä¸å®å ¨æ¯æas eè¯æ³æ¥æè·å¼å¸¸å¯¹è±¡ã使ç¨å®å¯è½å¯¼è´NameError: name 'e' is not definedã -
é误:
try: # ... some code that might fail ... except Exception as e: print("An error occurred:", e) -
æ£ç¡® (é¿éçç¥): 使ç¨ä¸å¸¦
as eçexcept忥æè·å¼å¸¸ï¼ä½è¿å°æ æ³è·åå¼å¸¸å¯¹è±¡çå ·ä½ä¿¡æ¯ãtry: # ... some code that might fail ... except: print("An error occurred")
-
-
ç¦æ¢å¸¦ä¸åçº¿çæ°ååé¢é:
- åå : PikaPython çè§£éå¨ä¸æ¯æ Python 3.6+ å¼å ¥çæ°åä¸å线åé符ã
- é误:
num = 1_000_000 - æ£ç¡®:
num = 1000000
-
ç¦æ¢å¤æçæè¨è¡¨è¾¾å¼:
-
åå : PikaPython çæè¨å¤ç䏿¯æå¤æçå¸å°è¡¨è¾¾å¼ï¼å¯è½å¯¼è´
TypeError: exceptions must derive from BaseExceptionã -
é误:
assert len(a) == len(b) == 0 -
æ£ç¡®:
assert len(a) == 0, "a should be empty" assert len(b) == 0, "b should be empty"
-
-
ç¦æ¢ in æä½ç¬¦ç¨äºåå ¸: åå : å¨ PikaPython ç for å¾ªç¯æ if 夿ä¸ç´æ¥ä½¿ç¨ key in dict ä¸è¢«æ¯æï¼æ¯å¯¼è´ test_example.py ä¸åºçº¿å½æ° (py_…) è¿è¡æ¶æåº KeyError çæå¸¸è§åå ã
æ£ç¡® (强å¶å®å ¨æ¨¡å¼): æææ¶ååå ¸è®¡æ°ææ¥è¯¢çåºçº¿å½æ°ï¼å¿ é¡»ç»ä¸éç¨ä»¥ä¸å¯ä¸å®å ¨æ¨¡å¼ï¼
# åå§åä¸ä¸ªç©ºåå
¸
counts = {}
for i in range(len(data)):
item = data[i]
# ç¬¬ä¸æ¥ï¼ä½¿ç¨ .get() è·åå½å计æ°ï¼æ³¨æï¼å¿
é¡»æ£æ¥æ¯å¦ä¸º None
current_count = counts.get(item)
if current_count is None:
# ç¬¬äºæ¥ï¼é®ä¸åå¨ï¼è®¾ç½®åå§å¼
counts[item] = 1
else:
# ç¬¬ä¸æ¥ï¼é®åå¨ï¼æ´æ°è®¡æ°
counts[item] = current_count + 1
-
ç¦æ¢ä½¿ç¨é¨åå ç½®å½æ° (å¦
sum()):-
åå : PikaPython çæ ååºå®ç°é常精ç®ï¼ä¸å 嫿æ Python çå ç½®å½æ°ï¼ä¾å¦
sum()ãè¿æ¯å¯¼è´è¿è¡æ¶NameError: name 'sum' is not definedçæå¸¸è§åå ä¹ä¸ã -
é误:
total = sum(my_list) -
æ£ç¡® (é¿éçç¥): ä½¿ç¨æå¨å¾ªç¯æ¥å®ç°ç¸åçåè½ã
total = 0 for x in my_list: total += x -
å ¶ä»åéå ç½®å½æ°: å æ¬ä½ä¸éäº
max(),min(),abs(),round()çãéå°NameErroræ¶ï¼é¦å æ£æ¥æ¯å¦ä½¿ç¨äºä¸æ¯æçå ç½®å½æ°ã
-
-
ç®æ³éæ©å¨åéç¯å¢ä¸çæè¡¡ (éè¦å éªç¥è¯):
- æ ¸å¿åå: å¨PikaPythonåéç¯å¢ä¸ï¼å®ç¨æ§ä¼å äºç论æä¼ãå®å¯éæ©æ¶é´å¤æåº¦è¾é«çç¡®å®å¯è¡ç®æ³ï¼ä¹ä¸è¦ä½¿ç¨å¯è½å¯¼è´è¿è¡æ¶å´©æºçé«æç®æ³ã
- å
¸åæ¡ä¾: 对äºè®¡æ°ç±»é®é¢ï¼ä¼å
使ç¨åéå¾ªç¯æå¨è®¡æ°ï¼O(n²)ï¼ï¼èéåå
¸è®¡æ°ï¼å¯è½è§¦å
KeyErroræè¯æ³ä¸æ¯æï¼ã - å³çåå: 妿æ åPythonå®ç°ä¾èµåå ¸ãå¤ææ°æ®ç»ææé«çº§è¯æ³ï¼åºä¸»å¨å¯»æ±çä»·çç®åå®ç°ï¼å³ä½¿æ§è½ç¨å·®ã
6.1.1 åºçº¿å½æ°å¢éä¿®å¤æµç¨ï¼å¼ºå¶ï¼
å½ py_... åºçº¿å¨ PikaPython ç¯å¢ä¸æ¥éæç»æå¼å¸¸æ¶ï¼å¿
é¡»æ§è¡ä»¥ä¸å°æ¥è¿ä»£ä¿®å¤ï¼ä¸å¾è·³è¿ä»»ä¸æ¥éª¤ãä¸å¾ç´æ¥æ¹ç¨ç¡¬ç¼ç æè¨ï¼
- æå°åéç°
- æååºæå°è¾å ¥æ°æ®ï¼å¯å°æ°æ®å表缩åå° 2~3 个å ç´ ï¼è§¦ååç±»é误ã
- ææ¶æ³¨éæä¸è¯¥å½æ°æ å ³çå ¶ä»æµè¯é»è¾ï¼èç¦å彿°ã
- è¯æ³æ¶æ
- éæ¡æ£æ¥ 6.1 åééå¶ï¼å»é¤ f-stringãä¸å
表达å¼ãå¤å
èµå¼ã
key in dictãsum()ãiter/nextãtry...except as eãä¸å线æ°åçã - è¥æåå
¸è®¡æ°é»è¾ï¼ç»ä¸æ¹ä¸º
val = d.get(k); if val is None: d[k] = 1 else: d[k] = val + 1模å¼ã
- éæ¡æ£æ¥ 6.1 åééå¶ï¼å»é¤ f-stringãä¸å
表达å¼ãå¤å
èµå¼ã
- ç»æç®å
- å°å¤å±å¤åè¡¨è¾¾å¼æè§£ä¸ºéè¡åéï¼é¿å ä¸è¡å å¤é»è¾ï¼ä¾¿äºå®ä½åªä¸è¡å¨è£åªè§£éå¨ä¸å¤±æï¼ã
- 鿥éªè¯
- æ¯æ¬¡ä» ä¿®æ¹ä¸ä¸ªè¯æ³/é»è¾ç¹åç«å³éæ°è¿è¡æå»ºä¸æµè¯ï¼åºç°æ°é误ç«å³åéä¸ä¸æ¹å¨å¹¶æ¹ç¨æ´åååæåæ¹å¼ã
- æ©å±åå½
- 卿尿°æ®éè¿åï¼æ¢å¤å®æ´ä¸¤ç»æµè¯æ°æ®ï¼4.1 è¦æ±ï¼ï¼å次éªè¯ä¸è´æ§ã
6.1.2 åºçº¿å½æ°è®¾è®¡çâé¿éä¼å âåå
å¨ç¼å Python åºçº¿å½æ° (py_…) æ¶ï¼é¦è¦ç®æ 䏿¯ä»£ç ç®æ´æä¼é ï¼èæ¯å¨ PikaPython çåéç¯å¢ä¸ç¨³å®è¿è¡ã为æ¤ï¼å¿ é¡»éµå¾ªä»¥ä¸ååï¼
é¿å åå ¸ï¼é¤éå¿ è¦ï¼å¦æç®æ³é»è¾å 许ï¼ä¼å èèä¸ä½¿ç¨åå ¸çå®ç°æ¹å¼ãä¾å¦å¯ä»¥éç¨åéå¾ªç¯æå¨è®¡æ°ï¼å¦æ¬æ¬¡å®è·µåæçæåæ¹æ¡ï¼ï¼è½ç¶æ¶é´å¤æåº¦è¾é«ï¼ä½è½100%è§é¿åå ¸ç¸å ³çè¿è¡æ¶é·é±ã å ç½®å½æ°é»ååï¼æç¡®ç¥æå¹¶è§é¿ PikaPython 䏿¯æçå ç½®å½æ°ãæå¸¸è§çæ¯ sum()ã任使¶åèåæä½ï¼æ±åãæ±ç§¯çï¼é½å¿ é¡»ä½¿ç¨æå¨å¾ªç¯å®ç°ã ç»ææåº¦æå¹³åï¼é¿å ä»»ä½åµå¥è¿æ·±çé»è¾ãå表æ¨å¯¼å¼ãçæå¨è¡¨è¾¾å¼çãææé»è¾åºæè§£ä¸ºæåºç¡ç for 循ç¯å if-else åæ¯ã æ ¸å¿ææ³ï¼å½ç®æ´æ§ä¸å ¼å®¹æ§å²çªæ¶ï¼æ æ¡ä»¶éæ©å ¼å®¹æ§ãä¸ä¸ªè½å¨ PikaPython 䏿£ç¡®è¿è¡çâ笨æâåºçº¿å½æ°ï¼è¿èäºä¸ä¸ªå¨æ å Python ä¸é«æä½æ æ³è¿è¡çâä¼é â彿°ã
6.1.3 æ¡ä¾ç»éªæè®ä¸æé
å车ä¹é´ï¼å¨å岿¨¡åå¼åä¸ï¼æä»¬ç»åäºä»å¤ææ¹æ¡å¤±è´¥å°ç®åæ¹æ¡æåç宿´è¿ç¨ã以䏿¯å ³é®æè®ï¼
-
PikaPythonç¯å¢éå¶è¡¥å :
- ç¦æ¢f-stringãä¸å 表达å¼ãå¤å èµå¼ã夿æè¨ãè¿ä»£å¨ãé¨åå ç½®å½æ°ï¼å¦sumãmaxãminãroundãabsçï¼ã
- printä» æ¯æéå·åéåæ°ï¼ç¦æ¢f-stringå.formatã
- åå
¸ä¸æ¯æ
key in dictï¼å¿ é¡»ç¨dict.get(key)å¹¶æ£æ¥Noneã - C端类åç³»ç»ä¸¥æ ¼åºå
Arg*ä¸PikaObj*ï¼è¿åå¼ç±»åå¿ é¡»ä¸æ¥å£å¤´æä»¶ä¸è´ã - å符串è¿åå¿
é¡»ç¨
obj_cacheStr()ï¼å¯¹è±¡è¿åç¨arg_newObj()ã - å表å
ç´ ç±»åé忝å¤çï¼ä¸è½ç´æ¥ç¨
getFloat读åintã - æ§è½æµè¯å¿ é¡»å¨åè½æè¨å ¨é¨éè¿åè¿è¡ï¼é¿å æ ææ°æ®ã
- æ§è½æµè¯åæ°éæ ¹æ®ç¯å¢å®é è°æ´ï¼é¿å è¶ æ¶ã
- å¤æå¯¹è±¡åµå¥ï¼å¦åå
¸å¼ä¸ºå表ï¼éç¨
arg_newObjå è£ ï¼ç¦æ¢ç¨setPtråæéã - æè¨è¡¨è¾¾å¼å¤æå¯¼è´è§£æå¤±è´¥ï¼éæå为ç®åæè¨ã
- ææå½æ°å ¥å£ä¼å å¤ç空å表ãNoneãè¶ççæ åµã
- ä»»ä½ç¡¬ç¼ç ã伪é é»è¾é½è§ä¸ºå¤±è´¥ï¼ç¦æ¢ä¸ºéè¿æµè¯èèåå®ç°ã
-
å ¸åæ¥éè¯æç»éªè¡¥å :
KeyErrorï¼æå¤§æ¦ç为åºçº¿å½æ°ç¨key in dictï¼éæ¹ä¸ºdict.get(key)模å¼ãNameErrorï¼å¸¸è§äºsumãmaxçå ç½®å½æ°æf-stringï¼éç¨æå¨å¾ªç¯æprintåéåæ°æ¿ä»£ãTypeError: exceptions must derive from BaseExceptionï¼æè¨è¡¨è¾¾å¼è¿äºå¤æï¼éæå为ç®åæè¨ãAssertion "self != 0" failedï¼Cç«¯æªæ£æ¥NULLæéï¼éå¨ç¨arg_getTypeåå NULL夿ãarg type not supportï¼C端è¿åäºåå§æéæç±»åä¸ç¬¦ï¼éç¨arg_newObjå è£ å¯¹è±¡ãconflicting typesç¼è¯é误ï¼C彿°è¿åç±»å䏿¥å£å¤´æä»¶ä¸ä¸è´ï¼éä¸¥æ ¼å¹é ãundefined reference to 'arg_incRef'ï¼APIä¸åå¨ï¼éç¨ç±»åæé 彿°å¦arg_newIntçãincompatible pointer typesï¼arg_newRefåæ°ç±»åé误ï¼éç¨arg_getPtræç´æ¥ç¨arg_newObjãValueError: invalid literal for int()ï¼æ°ååé¢é带ä¸å线ï¼éå»é¤ã
-
æä½³å®è·µä¸é¿éçç¥è¡¥å :
- ææåºçº¿å½æ°ä¼å ç¨æåºç¡for循ç¯åif-elseï¼é¿å ä»»ä½é«é¶è¯æ³ã
- åå ¸è®¡æ°ä¼å ç¨åéå¾ªç¯æ¿ä»£ï¼ä¿è¯ç¨³å®æ§ã
- è°è¯æ¶ä¼å å建æç®æµè¯ç¨ä¾ï¼éæ¥å¢éæ¢å¤ã
- C端ææå¯¹è±¡æä½åå¿ é¡»åç±»ååNULLæ£æ¥ã
- éå°APIä¸ç¡®å®æ¶ï¼ä¼å
ç¨
grep卿ºç 䏿¥æ¾ã - è®°å½ææAPIç¨æ³åä¿®å¤æ¨¡å¼ï¼å½¢æç¥è¯åºã
-
主å¨è°è¯ä¸å¢éä¿®å¤è¡¥å :
- å å®ç°æå°å¯è¿è¡çæ¬ï¼éæ¥æ·»å é»è¾ã
- æ¯æ¬¡ä¿®æ¹åç«å³ç¼è¯è¿è¡ï¼ééå³åéã
- è®°å½ææAPIç¨æ³åä¿®å¤ç»éªï¼å½¢æç¥è¯åºã
-
ä»£ç æ¢ç´¢é»éæ³åè¡¥å :
- APIä¸ç¡®å®æ¶ï¼ä¼å
ç¨
grepå¨pikapython-linux/pikapython/pikascript-core/PikaObj.hæ¥æ¾ã - è®°å½ææAPIç¨æ³åä¿®å¤ç»éªï¼å½¢æç¥è¯åºã
- APIä¸ç¡®å®æ¶ï¼ä¼å
ç¨
-
APIé·é±æé:
arg_incRef()彿°ä¸åå¨ï¼ä¸è¦å°è¯ä½¿ç¨ãarg_newRef()åæ°ç±»åä¸å¹é ï¼ææPikaObj*ï¼éArg*ï¼ã- è¿å
Arg*æ¶ï¼å¿ 须使ç¨arg_newInt()ãarg_newFloat()ãarg_newStr()çç±»åç¹å®æé 彿°ã
-
è¯æ³éå¶åæé:
sum()彿°ä¼å¯¼è´NameErrorï¼å¿ é¡»ç¨æå¨å¾ªç¯æ¿ä»£ã- å¨åéç¯å¢ä¸ï¼å®å¯éæ© O(n²) åé循ç¯ï¼ä¹ä¸è¦ä½¿ç¨å¯è½å´©æºçåå ¸æ¹æ¡ã
-
å¼åçç¥æé:
- éå° API ä¸ç¡®å®æ¶ï¼ç«å³ä½¿ç¨
grep卿ºç ä¸éªè¯ï¼èéçæµã - ç¼è¯é误æ¶ï¼ä»é误信æ¯ä¸å¦ä¹ æ£ç¡® APIï¼èéå°è¯”修夔é误信æ¯ã
- 彿 åç®æ³ä¸å¯è¡æ¶ï¼ä¸»å¨å¯»æ¾çä»·çç®åå®ç°ã
- éå° API ä¸ç¡®å®æ¶ï¼ç«å³ä½¿ç¨
-
è´¨éææ§æé:
- åè½æ£ç¡®æ§ä¼å äºæ§è½ä¼åã
- 任佔为äºéè¿æµè¯”ç硬ç¼ç 齿¯å¤±è´¥ã
- 夿¬¡å¤±è´¥åä»è¦åææ¾å°çæ£å¯è¡çæ¹æ¡ãæ´ä¸ªä»»å¡å¤±è´¥çæå¸¸è§æ ¹æºãå®å¯çºç²æ§è½ï¼ä¹è¦ä¿è¯åºçº¿å½æ°çè¯æ³å ¼å®¹æ§ã
-
åºäºæ¡ä¾çç»éªæè®:
- åå
¸æä½ç KeyError é·é±: PikaPython çåå
¸ä¸æ¯æ
key in dictè¯æ³ï¼ä¼å¯¼è´KeyErrorãå¿ é¡»ä½¿ç¨dict.get(key)模å¼å¹¶æ£æ¥è¿å弿¯å¦ä¸ºNoneã - æ··åæ°æ®ç±»å计æ°çç¥: å½éè¦å¤çå
å«ä¸åç±»åå
ç´ çå表æ¶ï¼ä½¿ç¨ç±»ååç¼é®çç¥ï¼å¦
"i_%ld"ã"f_%.6f"ã"s_%s"ï¼æ¯æä½³å®è·µï¼å¯ä»¥å®ç¾è§£å³åå ¸é®ç±»åéå¶ã - å®ç¨ä¸»ä¹ç®æ³éæ©: å¨åè½æ£ç¡®æ§åç论æä¼ä¹é´ï¼æ æ¡ä»¶éæ©å ¼å®¹æ§ãå®å¯ä½¿ç¨ O(n²) åé循ç¯è®¡æ°ï¼ä¹ä¸è¦ä½¿ç¨å¯è½å¯¼è´è¿è¡æ¶å´©æºçåå ¸æ¹æ¡ã
- ç¼è¯è¦åå¤ç: ä¿®å¤æ ¼å¼å符串类åä¸å¹é
ï¼å¦
%dvs%ldï¼è½ç¶ä¸å½±ååè½ï¼ä½åºåæ¶å¤ç以确ä¿ä»£ç è´¨éã - ç¯å¢å·®å¼ä¼å 认è¯: å¼ååå¿ é¡»æ·±å»çè§£ PikaPython çéå¶ï¼èéå设æ å Python å ¼å®¹æ§ãåå ¸æä½ãè¯æ³åéç齿¯å¸¸è§é·é±ã
- æµè¯æè¨ç®ååå: 卿µè¯èæ¬ä¸é¿å
夿çå¸å°è¡¨è¾¾å¼æè¨ï¼å¦
assert len(py_norm_empty) == len(c_norm_empty) == 0ï¼ï¼ä¼å 使ç¨ç®åæè¨ä»¥é² PikaPython è¯æ³è§£æå¤±è´¥ã - ç±»åæåå¥å£®æ§: å¨ C 代ç ä¸å¤çå表å
ç´ æ¶ï¼å¿
é¡»å
æ£æ¥
arg_getType()åè°ç¨å¯¹åºçarg_get*()彿°ï¼é¿å ç±»åä¸å¹é é误ã - è¾¹çæ åµä¼å å¤ç: 空å表ãNone å¼çè¾¹çæ åµåºå¨æ ¸å¿é»è¾åä¼å å¤çï¼ç¡®ä¿å½æ°é²æ£æ§ã
- æ§è½æµè¯é离: åè½æè¨å ¨é¨éè¿ååè¿è¡æ§è½æµè¯ï¼ç¡®ä¿åºåæµè¯å¨ç¸åç¯å¢ä¸è¿è¡ã
- åå
¸æä½ç KeyError é·é±: PikaPython çåå
¸ä¸æ¯æ
-
PikaPython æ ¸å¿éå¶ä¸ç¹æ§:
- ç²¾ç®æ ååº: PikaPython çæ ååºå®ç°é常精ç®ï¼ä¸æ¯æè®¸å¤ Python å
ç½®å½æ°ï¼å¦
sum(),max(),min(),abs(),round()çï¼ãéå°NameErroræ¶ï¼é¦å æ£æ¥æ¯å¦ä½¿ç¨äºä¸æ¯æçå ç½®å½æ°ã - è¯æ³åééå¶: ä» æ¯æ Python è¯æ³çåéï¼ç¦æ¢ f-stringãä¸å 表达å¼ãå¤å èµå¼ãè¿ä»£å¨æä½çãææé»è¾å¿ é¡»æè§£ä¸ºæåºç¡ç for 循ç¯å if-else 忝ã
- åå
¸å®ç°å·®å¼: PikaPython çåå
¸å®ç°ä¸æ å Python å卿¾èå·®å¼ï¼ä¸æ¯æ
key in dictæä½ï¼å¿ 须使ç¨dict.get(key)å¹¶æ£æ¥è¿åå¼ã - ç±»åç³»ç»ä¸¥æ ¼: C 代ç ä¸å¿
é¡»ä¸¥æ ¼åºå
Arg*ï¼éç¨å®¹å¨ï¼åPikaObj*ï¼å ·ä½å¯¹è±¡ï¼ï¼æ··æ·ä¼å¯¼è´ç¼è¯é误æè¿è¡æ¶å´©æºã - å
å管çç¹æ®: å符串è¿åå¿
须使ç¨
obj_cacheStr()ç¼åï¼å¦åå¯è½å¯¼è´æ¬åå¼ç¨ï¼å¯¹è±¡è¿åå¿ é¡»ä½¿ç¨arg_newObj()å è£ ã - 彿°ç¾åé·é±: C 彿°è¿åç±»åå¿
须䏿¥å£å¤´æä»¶ä¸¥æ ¼å¹é
ãè¿å
Arg*èæ¥å£ææPikaObj*ä¼å¯¼è´ç¼è¯é误 “conflicting types”ã - æ°æ®ç±»åæ··åå¤ç: å½å表å
å«
intåfloatæ¶ï¼å¿ é¡»å¨ C 代ç ä¸å æ£æ¥arg_getType()å使ç¨å¯¹åºçæå彿°ï¼é¿å ç±»åä¸å¹é ã - è¾¹çæ åµå¤ç: 空å表ãNone å¼çè¾¹çæ åµå¿ é¡»å¨å½æ°å ¥å£å¤ä¼å å¤çï¼ç¡®ä¿ç®æ³é²æ£æ§ã
- æµè¯èæ¬å ¼å®¹æ§: æè¨è¯å¥åºé¿å 夿å¸å°è¡¨è¾¾å¼ï¼ä¼å 使ç¨ç®åæ¯è¾ä»¥é² PikaPython è§£æå¤±è´¥ã
- ç²¾ç®æ ååº: PikaPython çæ ååºå®ç°é常精ç®ï¼ä¸æ¯æè®¸å¤ Python å
ç½®å½æ°ï¼å¦
åå
¥/è¦ç ./file_create/test_example.pyï¼ç»æä¸é¡ºåºå¿
é¡»å®å
¨ç¬¦å 4.1 / 4.2 è§èã
6.2 print 使ç¨éå¶
ä»
使ç¨éå·åéåæ°ï¼print("value:", x)ï¼ç¦æ¢ f-string / .format()ï¼å¦åå¯è½éé»å¤±æã
6.3 è½»éè¿è¡æ¶å·®å¼
æ ååºè¦çæéï¼å¦éâæ è¾åºâæè¡ä¸ºå·®å¼ï¼åºä¼å æçè¿è¡æ¶è£åªã
7 è°è¯ä¸æ éææ¥
7.1 Segmentation fault å¢éå®ä½çç¥
- æç®åï¼ç¼©åå° 1 个æå°å¯è¡å½æ°ï¼C 䏿µè¯åæ¥ç²¾ç®ï¼ã
- éªè¯åºçº¿ï¼å 确认æç®çæ¬å¯æå»ºä¸è¿è¡ã
- å¢éæ·»å ï¼ä¸æ¬¡æ·»å ä¸ä¸ªå°é»è¾æå½æ°ã
- 鿥æµè¯ï¼æ¯æ¬¡æ·»å åç«å³æå»º & æ§è¡ãå¦åºç°æ®µé误ï¼å³å®ä½äºæè¿å¢éã
7.1.1 åºäºåææ¥åçè¯æç»éª
-
彿°ç¾åç±»åå²çªè¯æ:
- ç°è±¡: ç¼è¯æ¶åºç°
error: conflicting types for 'function_name'; have 'Arg *(PikaObj *, PikaObj *)' but want 'PikaObj *(PikaObj *, PikaObj *)'ã - åå : C 彿°å®ç°ä¸çè¿åç±»å䏿¥å£å¤´æä»¶ (.pyi çæç .h æä»¶) ä¸å£°æçè¿åç±»åä¸å¹é
ãé常æ¯è¿åäº
Arg*使¥å£ææPikaObj*ï¼åä¹äº¦ç¶ã - è¯ææ¥éª¤:
- æ£æ¥çæç头æä»¶ä¸ç彿°å£°æã
- å¯¹æ¯ C å®ç°æä»¶ä¸ç彿°ç¾åã
- 确认è¿åç±»åæ¯å¦å¹é
ï¼
PikaObj*vsArg*ï¼ã
- ä¿®å¤æ¨¡å¼: æ ¹æ®æ¥å£è¦æ±è°æ´å½æ°ç¾åã对äºè¿å对象çæ
åµï¼ä½¿ç¨
PikaObj*å¹¶è¿åNULL表示 Noneï¼å¯¹äºå¯è½è¿å对象æ None çæ åµï¼ä½¿ç¨Arg*å¹¶ç¨arg_newObj()å è£ å¯¹è±¡ã
- ç°è±¡: ç¼è¯æ¶åºç°
-
arg_newRef åæ°ç±»åä¸å¹é è¯æ:
- ç°è±¡: ç¼è¯æ¶åºç°
error: incompatible pointer typesæè¿è¡æ¶å´©æºã - åå :
arg_newRef()彿°æææ¥æ¶PikaObj*ç±»åï¼ä½ä¼ å ¥çæ¯Arg*ç±»åã - è¯ææ¥éª¤:
- æ£æ¥ææ
arg_newRef()è°ç¨ï¼ç¡®ä¿åæ°æ¯PikaObj*ç±»åã - 妿éè¦ä»
Arg*转æ¢ä¸ºPikaObj*ï¼ä½¿ç¨arg_getPtr()彿°ã - éªè¯å¯¹è±¡çå½å¨æï¼ç¡®ä¿è¿åç对象å¨å½æ°ä½ç¨åå ææã
- æ£æ¥ææ
- ä¿®å¤æ¨¡å¼:
return arg_newRef(arg_getPtr(arg));èéç´æ¥return arg_newRef(arg);ã
- ç°è±¡: ç¼è¯æ¶åºç°
-
NULL æéæè¨å¤±è´¥è¯æ:
- ç°è±¡: è¿è¡æ¶åºç°
Assertion 'obj != NULL' failedæç±»ä¼¼å´©æºã - åå : å¨è°ç¨
arg_getType()æå ¶ä»éè¦ææå¯¹è±¡ç彿°åï¼æªæ£æ¥å¯¹è±¡æ¯å¦ä¸º NULLã - è¯ææ¥éª¤:
- æ£æ¥ææ
arg_getType()è°ç¨åæ¯å¦æ NULL æ£æ¥ã - éªè¯åæ°è·åé»è¾ï¼ç¡®ä¿
arg_getPtr()è¿åå¼ä¸ä¸º NULLã - æ·»å é²å¾¡æ§ç¼ç¨ï¼
if (NULL == obj) return arg_newNone();ã
- æ£æ¥ææ
- ä¿®å¤æ¨¡å¼: 卿æå¯¹è±¡æä½åæ·»å NULL æ£æ¥ã
- ç°è±¡: è¿è¡æ¶åºç°
-
ç¼è¯è¦åçç³»ç»æ§å¤ç:
- æ ¼å¼å符串è¦å:
%dvs%ldç±»åä¸å¹é ï¼è½ç¶ä¸å½±ååè½ï¼ä½åºç»ä¸ä½¿ç¨%ldï¼long intï¼ã - æªä½¿ç¨åéè¦å: ç§»é¤ææ³¨éææªä½¿ç¨çåé声æã
- éå¼å£°æè¦å: ç¡®ä¿ææå½æ°é½ææ£ç¡®çåå声æã
- å¤çåå: å³ä½¿è¦åä¸å½±åè¿è¡ï¼ä¹åºåæ¶ä¿®å¤ä»¥ç»´æ¤ä»£ç è´¨éã
- æ ¼å¼å符串è¦å:
-
æ§è½éªè¯çå®ç¨æ¹æ³:
- åºåæµè¯: 使ç¨
time.time()è®°å½å¼å§åç»ææ¶é´ï¼è®¡ç®æ§è½æååæ°ã - æ£ç¡®æ§éªè¯: ç¡®ä¿ C 模åè¾åºä¸ Python åºåå®å ¨ä¸è´ã
- æ¸è¿å¼ä¼å: å å®ç°åè½æ£ç¡®ï¼åè¿½æ±æ§è½ä¼åã
- åºåæµè¯: 使ç¨
7.2 é误è¾åºæ ¼å¼
è¯æ³æ£æ¥å¤±è´¥ï¼[ERROR] <æè¿°>
æå»ºå¤±è´¥ï¼[BUILD_FAIL] <æè¦>
è¿è¡å¤±è´¥ï¼[RUN_FAIL] <æè¦>
æåï¼ç»ä¸ [MODULE] åï¼è§ç¬¬ 8 èï¼ã
7.2.1 è¿è¡æ¶éè¯¯è¯æç»éªï¼arg type not support
- éè¯¯åºæ¯: å½ä½ å¨ Python æµè¯èæ¬ä¸å¯¹ä¸ä¸ªåéè°ç¨ä¸ä¸ªå½æ°ï¼ä¾å¦
len(my_var)ï¼ï¼ä½ PikaPython è¿è¡æ¶æåº[Error] len: arg type not supporté误ã - æ ¸å¿åå : è¿å 乿»æ¯æå³ç
my_varåéçå®é ç±»åä¸ä½ ææçç±»åä¸ç¬¦ãæå¸¸è§çæ 嵿¯ï¼- ä½ ææå®æ¯ä¸ä¸ªå表 (
list)ãåå ¸ (dict) æå ¶ä»å¯è¿ä»£å¯¹è±¡ã - ä½å®å®é
䏿¯ä¸ä¸ªæ´æ° (
int)ãæéå°å (0x...) æå ¶ä»ä¸æ¯æè¯¥æä½çç±»åã
- ä½ ææå®æ¯ä¸ä¸ªå表 (
- è¯ææ¥éª¤:
- ç¡®è®¤æ¥æº: è¿ä¸ªå鿝ä»åªéæ¥çï¼å¦æå®æ¥èª C 模åçè¿åå¼ï¼é£ä¹é®é¢å ä¹å¯ä»¥ 100% å®ä½å° C 模åçå®ç°ä¸ã
- æ£æ¥ C å®ç°:
- æéé·é±: ä½ æ¯å¦å¨ C 代ç ä¸é误å°è¿åäºä¸ä¸ªåå§æéè䏿¯ä¸ä¸ªPikaPython 对象ï¼
- å¸¸è§æ¡ä¾: å¨åå
¸ä¸åå¨å表æ¶ï¼é误å°ä½¿ç¨äº
pikaDict_setPtr()è䏿¯pikaDict_set(..., arg_newObj(...))ãåè åªåäºå°åï¼å¯¼è´ Python 端æ¶å°äºä¸ä¸ªæ´æ°ï¼ä»èå¨è°ç¨len()æ¶æ¥éã
- éªè¯çç¥: å¨ Python æµè¯èæ¬ä¸ï¼ç´æ¥
print()è¿ä¸ªåºé®é¢çåéãå¦æä½ çå°çæ¯ä¸ä¸ª0x...æ ¼å¼çå°åï¼é£ä¹å°±å¯ä»¥å®å ¨ç¡®å®æ¯ C 端ç对象å è£ åºäºé®é¢ã
- è§£å³æ¹å: ä¸è¦è¯å¾å¨ Python æµè¯èæ¬ä¸âä¿®å¤âè¿ä¸ªé®é¢ï¼ä¾å¦ï¼å°è¯è½¬æ¢ç±»åï¼ãå¿
é¡»åå° C æºä»£ç ï¼ä½¿ç¨æ£ç¡®ç APIï¼å¦
arg_newObjï¼æ¥å è£ åè¿å对象ã
7.2.2 è¿è¡æ¶éè¯¯è¯æç»éªï¼IndexError: index out of range
- éè¯¯åºæ¯: å¨
test_example.pyè¿è¡æ¶ï¼åºç°IndexError: index out of rangeã - æ ¸å¿åå : è¿é叏䏿¯ C 模åçé®é¢ï¼èæ¯ Python åºçº¿æµè¯å½æ° (
py_...) å¨ PikaPython çåéè¿è¡ç¯å¢ä¸åºç°äºé®é¢ãPikaPython 对 Python è¯æ³çæ¯ææ¯åéï¼ä¸äºå¨æ å Python ä¸åæ³çæä½ï¼ç¹å«æ¯æ¶ååå ¸åè¿ä»£å¨ï¼å¯è½ä¼å¤±è´¥ã - è¯ææ¥éª¤:
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
test_example.py) ä¸ï¼è䏿¯ C 模åçæ§è¡ã - æ£æ¥è¯æ³éå¶: å顾 Python åºçº¿å½æ°çå®ç°ï¼æ£æ¥æ¯å¦ä½¿ç¨äº PikaPython 䏿¯ææè¡ä¸ºä¸ä¸è´çè¯æ³ï¼ä¾å¦
key in dictã
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
- è§£å³æ¹å:
- å¯ä¸å 许路å¾ï¼ä¿®æ£ Python åºçº¿å½æ°ãæç § 6.1 ä¸ 6.1.1 çåéä¸å¢éä¿®å¤æµç¨è¿è¡æå°åãæåãéªè¯ãç¦æ¢æ¹ç¨ç¡¬ç¼ç 常éç»è¿åºçº¿é»è¾ã
- å¦å¨ä¸¥æ ¼æ§è¡ 6.1.1 䏿¥å仿 æ³ç¨³å®ï¼è¿ç» 3 次è¿ä»£å¤±è´¥ï¼ï¼åºç»æ¢å¹¶æ¥å
[DEGRADED_SEMANTICS]ï¼èéè·³è¿åºçº¿ã
7.2.3 è¿è¡æ¶éè¯¯è¯æç»éªï¼Assertion "self != 0" failed
-
éè¯¯åºæ¯: C æ¨¡åæ§è¡æ¶ï¼ç¨åºå
Abortedéåºï¼æ¥å¿æ¾ç¤ºAssertion "self != 0" failed, in function: arg_getType()ã -
æ ¸å¿åå : è¿æ¯ä¸ä¸ªç©ºæéæè¨å¤±è´¥ã宿å³çä¸ä¸ª
NULLæéè¢«ä¼ éç»äºarg_getType()彿°ï¼èè¯¥å½æ°ææä¸ä¸ªææçArg*åæ°ãè¿å 乿»æ¯ç±pikaDict_get()æpikaList_get()çæ¥æ¾å½æ°å¨æªæ¾å°æå®å 容æ¶è¿åNULLï¼è䏿¯ä¸ä¸ªARG_TYPE_NONEçArg*对象ï¼å¼èµ·çã -
è¯ææ¥éª¤:
- å®ä½æ¥æº: æ¾å°æ¥å¿ä¸å¤±è´¥ç
arg_getType()è°ç¨å¨ C æºç ä¸çä½ç½®ã - è¿½æº¯ä¸æ¸¸: æ¥çè¢«ä¼ å
¥
arg_getType()çé£ä¸ªArg*å鿝ä»åªéè·åçã大æ¦çæ¯æ¥èªä¸ä¸ªpikaDict_get()æpikaList_get()çè°ç¨ã - 确认é®é¢: è¿è¡¨æä¸æ¸¸çæ¥æ¾æä½å¤±è´¥äºï¼ä¾å¦ï¼åå
¸ä¸ä¸åå¨è¯¥é®ï¼ï¼å¹¶ä¸å
¶è¿åç
NULL弿ªç»æ£æ¥å°±ç´æ¥è¢«ä½¿ç¨äºã
- å®ä½æ¥æº: æ¾å°æ¥å¿ä¸å¤±è´¥ç
-
è§£å³æ¹å: å¿ é¡»å¨ä½¿ç¨
pikaDict_get()æpikaList_get()çè¿åå¼ä¹åï¼æ·»å ä¸ä¸ªNULLæéæ£æ¥ã// éè¯¯ï¼æªæ£æ¥ pikaDict_get çè¿åå¼ Arg* count_arg = pikaDict_get(counts, key); if (arg_getType(count_arg) == ARG_TYPE_NONE) { // 妿 count_arg æ¯ NULLï¼è¿éä¼å´©æº // ... } // æ£ç¡®ï¼å¨ä½¿ç¨åè¿è¡ NULL æ£æ¥ Arg* count_arg = pikaDict_get(counts, key); if (count_arg == NULL) { // é®ä¸åå¨ï¼è¿åäº NULL // å¤çé®ä¸åå¨çæ åµï¼ä¾å¦è®¾ç½®åå§å¼ pikaDict_setInt(counts, key, 1); } else { // é®åå¨ï¼å¯ä»¥å®å ¨å°ä½¿ç¨ count_arg int current_count = arg_getInt(count_arg); pikaDict_setInt(counts, key, current_count + 1); }
7.2.4 è¿è¡æ¶éè¯¯è¯æç»éªï¼KeyError
- éè¯¯åºæ¯: å¨
test_example.pyè¿è¡æ¶ï¼åºç°KeyErrorï¼å°¤å ¶æ¯å¨è®¿é®åå ¸æ¶ã - æ ¸å¿åå : è¿æå¤§æ¦çä¸
py_...åºçº¿å½æ°ä¸çåå ¸æä½æå ³ï¼ç¹å«æ¯å½ä½¿ç¨äº PikaPython 䏿¯æçinæä½ç¬¦æ¶ãPikaPython çdictå®ç°ä¸æ å Python åå¨å·®å¼ï¼å¯¼è´inå ³é®åçè¡ä¸ºä¸ç¬¦å颿ã - è¯ææ¥éª¤:
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
test_example.py) ä¸ãé误æ¥å¿é叏伿åpy_...彿°ä¸çæä¸è¡ã - æ£æ¥è¯æ³éå¶: ç«å³æ£æ¥è¯¥è¡æéè¿ä»£ç æ¯å¦ä½¿ç¨äº
if key in dict:è¯æ³ã
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
- è§£å³æ¹å: (1) 强å¶ä¿®å¤: ç«å³ä½¿ç¨ val = dict_obj.get(k) æ¨¡å¼æ¿ä»£ k in dict_objã (2) 主å¨è§é¿ (æ¨è): å¦æä¿®å¤åé®é¢ä¾ç¶å卿é»è¾è¿äºå¤æï¼åºæææ¾å¼åå ¸æ¹æ¡ï¼éæåºçº¿å½æ°ä¸ºä¸ä¾èµåå ¸ç纯å表æä½ï¼å¦åé循ç¯è®¡æ°ï¼ãè¿æ¯æ¬æ¬¡å®è·µä¸éªè¯è¿çãæå¯é çç»æè§£å³æ¹æ¡ã (3) 严ç¦ä¸ºäºç»è¿æ¤é误èç´æ¥ä¸ç¡¬ç¼ç 常éè¿è¡æ¯è¾ã
7.2.5 è¿è¡æ¶éè¯¯è¯æç»éªï¼ValueError: invalid literal for int()
- éè¯¯åºæ¯: å¨
test_example.pyè¿è¡æ¶ï¼åºç°ValueError: invalid literal for int()ï¼å°¤å ¶æ¯å¨å¤çæ°åæ¶ã - æ ¸å¿åå : è¿é常æ¯ç±äºå¨ Python 代ç ä¸ä½¿ç¨äº PikaPython 䏿¯æçæ°åæ ¼å¼ã
- è¯ææ¥éª¤:
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
test_example.py) ä¸ã - æ£æ¥è¯æ³éå¶: æ£æ¥æ¯å¦ä½¿ç¨äºå¸¦ä¸åçº¿çæ°ååé¢éï¼å¦
1_000_000ï¼ã
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
- è§£å³æ¹å:
- ä¿®æ£ Python 代ç : ç§»é¤æ°åä¸çä¸å线ï¼ä¾å¦ï¼å°
1_000_000æ¹ä¸º1000000ï¼ã
- ä¿®æ£ Python 代ç : ç§»é¤æ°åä¸çä¸å线ï¼ä¾å¦ï¼å°
7.2.6 è¿è¡æ¶éè¯¯è¯æç»éªï¼NameError
- éè¯¯åºæ¯: å¨
test_example.pyè¿è¡æ¶ï¼åºç°NameError: name 'xxx' is not definedã - æ ¸å¿åå : è¿é常æå³çä½ ä½¿ç¨äº PikaPython çç²¾ç®è¿è¡æ¶æä¸æ¯æçï¼
- å
ç½®å½æ°: ä¾å¦
sumã - è¯æ³ç»æ: ä¾å¦ f-string (
f"...")ï¼å®å¨ PikaPython ä¸è¢«å½ä½ä¸ä¸ªæ®éçåéåï¼ä»è导è´NameErrorã
- å
ç½®å½æ°: ä¾å¦
- è¯ææ¥éª¤:
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
test_example.py) ä¸ã - æ£æ¥åç§°
xxx:- 妿
xxxæ¯ä¸ä¸ªå½æ°ï¼å¦sumï¼ï¼è¯´æå®ä¸è¢«æ¯æã - 妿
xxxçèµ·æ¥åä¸ä¸ª f-stringï¼å¦f"Test failed..."ï¼ï¼è¯´æ f-string è¯æ³ä¸è¢«æ¯æã
- 妿
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
- è§£å³æ¹å:
- æ¿æ¢ææå¨å®ç°: å°ä¸æ¯æç彿°ï¼å¦
sum()ï¼æ¿æ¢ä¸ºæå¨å¾ªç¯ã - 使ç¨å
¼å®¹è¯æ³: å° f-string æ¿æ¢ä¸º
print()çå¤åæ°å½¢å¼åif夿ã
- æ¿æ¢ææå¨å®ç°: å°ä¸æ¯æç彿°ï¼å¦
7.2.7 ç¼è¯éè¯¯è¯æç»éªï¼undefined reference to 'arg_incRef'
-
éè¯¯åºæ¯: ç¼è¯æ¶åºç°
undefined reference to 'arg_incRef'æç±»ä¼¼ “implicit declaration” è¦åã -
æ ¸å¿åå : å°è¯ä½¿ç¨äºä¸åå¨çAPI彿°ãPikaPythonçAPIå¯è½ä¸é¢æä¸ç¬¦ï¼æäºå½æ°åä¸å卿ç¾åä¸åã
-
è¯ææ¥éª¤:
- æ£æ¥å½æ°å: 确认æ¯å¦ä½¿ç¨äºæ£ç¡®çAPIã
arg_incRefä¸åå¨ï¼åºä½¿ç¨ç±»åç¹å®çæé 彿°ã - æ¥æ¾æ¿ä»£æ¹æ¡: 使ç¨
grepå¨å¤´æä»¶ä¸æç´¢ç¸å ³APIï¼æåèç°ææåæ¡ä¾ã
- æ£æ¥å½æ°å: 确认æ¯å¦ä½¿ç¨äºæ£ç¡®çAPIã
-
è§£å³æ¹å:
-
使ç¨ç±»åæé 彿°: ä¸è¦å°è¯å¼ç¨ç°æå¯¹è±¡ï¼èæ¯å建æ°çï¼
// é误 return arg_incRef(existing_arg); // æ£ç¡® if (arg_getType(existing_arg) == ARG_TYPE_INT) { return arg_newInt(arg_getInt(existing_arg)); }
-
7.2.8 è¿è¡æ¶éè¯¯è¯æç»éªï¼incompatible pointer types (arg_newRef)
- éè¯¯åºæ¯: ç¼è¯æ¶åºç°
passing argument 1 of 'arg_newRef' from incompatible pointer typeè¦åï¼æè¿è¡æ¶æ®µé误ã - æ ¸å¿åå :
arg_newRefææPikaObj*åæ°ï¼ä½ä¼ éäºArg*ç±»åãAPIåæ°ç±»åä¸å¹é 导è´çç±»åé误ã - è¯ææ¥éª¤:
- æ£æ¥åæ°ç±»å: ç¡®è®¤ä¼ éç»API彿°çåæ°ç±»åæ¯å¦æ£ç¡®ã
- çè§£Arg vs PikaObj:
Arg*æ¯éç¨å®¹å¨ï¼PikaObj*æ¯å ·ä½å¯¹è±¡ãæ··æ·è¿ä¸¤ç§ç±»åæ¯å¸¸è§é误ã
- è§£å³æ¹å:
- é¿å
arg_newRef: è¯¥å½æ°å¯è½ä¸éåç´æ¥è¿åArgå¯¹è±¡ãæ¹ç¨ç±»åç¹å®çæé 彿°æ
arg_newObj()å è£ PikaObjã
- é¿å
arg_newRef: è¯¥å½æ°å¯è½ä¸éåç´æ¥è¿åArgå¯¹è±¡ãæ¹ç¨ç±»åç¹å®çæé 彿°æ
7.2.9 ç¼è¯éè¯¯è¯æç»éªï¼format '%d' expects argument of type 'int', but argument has type 'int64_t'
- éè¯¯åºæ¯: ç¼è¯æ¶åºç°
format '%d' expects argument of type 'int', but argument has type 'int64_t'è¦åã - æ ¸å¿åå : å¨ C 代ç ä¸ä½¿ç¨
snprintfæprintfæ¶ï¼æ ¼å¼è¯´æç¬¦ä¸å®é åæ°ç±»åä¸å¹é ãPikaPython 䏿äºå¼å¯è½æ¯int64_tç±»åï¼ä½ä½¿ç¨äº%dèé%ldã - è¯ææ¥éª¤:
- æ£æ¥æ ¼å¼å符串: æ¾å°åºç°è¦åç
snprintfè°ç¨ã - ç¡®è®¤åæ°ç±»å: æ£æ¥ä¼ éçåæ°æ¯å¦ä¸º
int64_tæå ¶ä» 64 ä½ç±»åã
- æ£æ¥æ ¼å¼å符串: æ¾å°åºç°è¦åç
- è§£å³æ¹å:
- ä½¿ç¨æ£ç¡®çæ ¼å¼è¯´æç¬¦: 对äº
int64_t使ç¨%ldï¼å¯¹äºdouble使ç¨%.6fçã - ç±»å转æ¢: 妿å¿
è¦ï¼ä½¿ç¨
(long)æ(int)è¿è¡æ¾å¼è½¬æ¢ã
- ä½¿ç¨æ£ç¡®çæ ¼å¼è¯´æç¬¦: 对äº
7.2.10 è¿è¡æ¶éè¯¯è¯æç»éªï¼KeyError (åå
¸æä½)
- éè¯¯åºæ¯: å¨
test_example.pyè¿è¡æ¶ï¼åºç°KeyErrorï¼å°¤å ¶æ¯å¨è®¿é®åå ¸æ¶ã - æ ¸å¿åå : è¿æå¤§æ¦çä¸
py_...åºçº¿å½æ°ä¸çåå ¸æä½æå ³ï¼ç¹å«æ¯å½ä½¿ç¨äº PikaPython 䏿¯æçinæä½ç¬¦æ¶ãPikaPython çdictå®ç°ä¸æ å Python åå¨å·®å¼ï¼å¯¼è´inå ³é®åçè¡ä¸ºä¸ç¬¦å颿ã - è¯ææ¥éª¤:
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
test_example.py) ä¸ãé误æ¥å¿é叏伿åpy_...彿°ä¸çæä¸è¡ã - æ£æ¥è¯æ³éå¶: ç«å³æ£æ¥è¯¥è¡æéè¿ä»£ç æ¯å¦ä½¿ç¨äº
if key in dict:è¯æ³ã
- å®ä½é误æº: 确认é误åçå¨ Python 代ç (
- è§£å³æ¹å:
(1) 强å¶ä¿®å¤: ç«å³ä½¿ç¨
val = dict_obj.get(k); if val is None: ...æ¨¡å¼æ¿ä»£k in dict_objã (2) 主å¨è§é¿ (æ¨è): å¦æä¿®å¤åé®é¢ä¾ç¶å卿é»è¾è¿äºå¤æï¼åºæææ¾å¼åå ¸æ¹æ¡ï¼éæåºçº¿å½æ°ä¸ºä¸ä¾èµåå ¸ç纯å表æä½ï¼å¦åé循ç¯è®¡æ°ï¼ãè¿æ¯æ¬æ¬¡å®è·µä¸éªè¯è¿çãæå¯é çç»æè§£å³æ¹æ¡ã (3) 严ç¦ä¸ºäºç»è¿æ¤é误èç´æ¥ä¸ç¡¬ç¼ç 常éè¿è¡æ¯è¾ã
7.3 主å¨ä»£ç æ¢ç´¢é»éæ³å (grep çå¦ç¨)
å½ä½ 对 API çå
·ä½åç§°ãåæ°æç¨æ³ä¸ç¡®å®æ¶ï¼å¼ºçé¼å±ä½ ä½¿ç¨ grep çå½ä»¤è¡å·¥å
·ç´æ¥å¨é¡¹ç®æºä»£ç ä¸è¿è¡æ¢ç´¢ãè¿æ¯ä¸ç§æ¯è¢«å¨æ¥é
ææ¡£æ´é«æãæ´åç¡®çæ¹æ³ã
-
éç¨åºæ¯:
- éå°âæªå®ä¹å¼ç¨ (undefined reference)âæâéå¼å£°æ (implicit declaration)âç¼è¯é误ã
- ä¸ç¡®å®æä¸ªåè½ç API 彿°åï¼ä¾å¦ï¼æ¯
pikaList_len,pika_list_lenè¿æ¯pika_list_lengthï¼ã - æ³è¦æ¥æ¾æä¸ªå®æç±»åçå®ä¹ã
-
é»éæä½èä¾:
-
å®ä½æ ¸å¿å¤´æä»¶: PikaPython çç»å¤§å¤æ°æ ¸å¿ API é½å®ä¹å¨
pikapython-linux/pikapython/pikascript-core/PikaObj.hã -
使ç¨
grepç²¾åæç´¢:# 示ä¾ï¼å½ä¸ç¡®å®å表é¿åº¦å½æ°çåç¡®åç§°æ¶ï¼ # æç´¢å å« "pikaList" å "len" çè¡ grep -n "pikaList" ./pikapython-linux/pikapython/pikascript-core/PikaObj.h | grep "len" # 示ä¾ï¼å®½æ³å°æç´¢ä¸ "pikaList" ç¸å ³çææ API grep -n "pikaList" ./pikapython-linux/pikapython/pikascript-core/PikaObj.h | head -20
-
-
æ ¸å¿ä»·å¼: è¿ç§æ¹æ³è½è®©ä½ èªä¸»åç°æåç¡®ãææ°ç API ç¨æ³ï¼åå°å ä¿¡æ¯ä¸å ¨æè§å鿼坼è´çé误éè¯ï¼æ¯æä¸ºé«çº§é®é¢è§£å³è çå ³é®ä¸æ¥ã
7.4 è¯ä¹å®æ´æ§ååä¸é忥å
- é¦è¦åå: ä½ çæ ¸å¿ç®æ æ¯çæè¯ä¹æ£ç¡®ç C 模åãä»»ä½å½¢å¼ç硬ç¼ç ãå ä½ç¬¦æä¼ªé é»è¾ï¼å³ä¸ºäºéè¿æµè¯èè¿ååºå®å¼ï¼é½çåäºä»»å¡å¤±è´¥ã
- é忥å: å¦æä½ å ç¥è¯éå¶æ API éç¢èæ æ³å®ç°å®æ´çãæ£ç¡®çé»è¾ï¼ä¸¥ç¦æäº¤èåå®ç°ã
- æåå¤å®: ä»»ä½å
å«
[DEGRADED_SEMANTICS]æ ç¾çä¼è¯é½ä¸ä¼è¢«å¤å®ä¸ºæåã
7.5 主å¨è°è¯æä½³å®è·µ
é¤äºè¢«å¨å°ååºéè¯¯ï¼æ´é«æççç¥æ¯ä¸»å¨éç¨ç³»ç»æ§çè°è¯æ¹æ³æ¥å¿«éå®ä½é®é¢ã
-
å®è·µä¸ï¼å建å°åãç¬ç«çæµè¯ç¨ä¾
- åºæ¯: å½ä¸ä¸ªå¤æçæµè¯ç¨ä¾å¤±è´¥æ¶ï¼å¾é¾ç¡®å®æ¯åªä¸ªè¾å ¥æé»è¾åæ¯å¯¼è´äºé®é¢ã
- çç¥: ä¸è¦ç´æ¥å¨åå§ç
test_example.pyä¸åå¤ä¿®æ¹ãå建ä¸ä¸ªæ°çã临æ¶ç Python æä»¶ï¼ä¾å¦debug_test.pyï¼ï¼å¨å ¶ä¸åªå 嫿ç®åçä»£ç æ¥å¤ç°é®é¢ã - æ¥éª¤:
- é离: ä»å¤æçè¾å ¥æ°æ®ä¸æååºè½è§¦å bug çæå°åéã
- ç®å: ç¼åä¸ä¸ªåªè°ç¨é®é¢ C 彿°çæç® Python èæ¬ã
- è¿è¡: 使ç¨
python run_pika.pyç¬ç«è¿è¡è¿ä¸ªè°è¯èæ¬ã
- ä¼å¿: è¿ç§æ¹æ³å¯ä»¥å¿«ééªè¯å ³äº bug çåè®¾ï¼æé¤å¹²æ°å ç´ ï¼å¹¶æ¾èå å¿«å®ä½é度ã
-
å®è·µäºï¼å¨ C 代ç 䏿å°ä¸é´åé
-
åºæ¯: å½ C 模åçæç»è¾åºä¸ç¬¦å颿ï¼ä¾å¦ï¼è¿åäº
Noneãé误ç计æ°å¼æç©ºå表ï¼ï¼ä½ç¨åºæ²¡æå´©æºæ¶ã -
çç¥: å¨ C 彿°çå ³é®é»è¾ç¹ï¼ä½¿ç¨
printfæå°åºä¸é´åéçå¼ãè¿å¯ä»¥è®©ä½ æ¸ æ°å°è¿½è¸ªç®æ³çæ§è¡æµç¨åæ°æ®ç¶æã -
æ¥éª¤:
-
å å«å¤´æä»¶: ç¡®ä¿ C æä»¶é¡¶é¨æ
#include <stdio.h>ã -
æ¤å ¥æå°è¯å¥: å¨å¾ªç¯å é¨ãæ¡ä»¶å¤æåæ¯ãè¿åå¼ä¹åçå ³é®ä½ç½®æ·»å
printfãä¸ºäºæ¹ä¾¿å¨æ¥å¿ä¸è¯å«ï¼å¯ä»¥å ä¸ç¹æ®åç¼ã// 示ä¾ï¼å¨å¾ªç¯ä¸æå°è®¡æ°å¼ printf("[DEBUG] Key: %s, Current Count: %d\n", key, current_count); -
éæ°æå»ºåè¿è¡: æ§è¡
python run_pika.py ...ã -
åææ¥å¿: å¨
compile.logï¼å¦æprintf导è´ç¼è¯éè¯¯ï¼ærun.log䏿¥æ¾ä½ ç[DEBUG]è¾åºï¼è§å¯åéçå忝å¦ç¬¦å颿ã
-
-
注æ: è°è¯å®æåï¼åºç§»é¤ææ³¨éæè¿äº
printfè¯å¥ã
-
-
å®è·µä¸ï¼APIå¦ä¹ ä¸é误驱å¨å¼å
- åºæ¯: 对PikaPython APIä¸çæï¼å¯¼è´å¤æ¬¡ç¼è¯åè¿è¡æ¶é误ã
- çç¥: éç¨æ¸è¿å¼APIæ¢ç´¢ï¼ä»é误信æ¯ä¸å¦ä¹ æ£ç¡®çç¨æ³ã
- æ¥éª¤:
- ä»ç®åå¼å§: å å®ç°æåºæ¬çé»è¾ï¼ä½¿ç¨å·²ç¥å¯è¡çAPIã
- é误驱å¨å¦ä¹ : å½éå°ç¼è¯é误æ¶ï¼ä¸è¦çæµï¼èæ¯ä½¿ç¨
grep卿ºç 䏿¥æ¾æ£ç¡®APIã - å°æ¥éªè¯: æ¯æ¬¡åªå°è¯ä¸ä¸ªæ°çAPIè°ç¨ï¼ç«å³ç¼è¯éªè¯ã
- è®°å½æ¨¡å¼: å°å¦å°çAPI模å¼è®°å½ä¸æ¥ï¼é¿å éå¤ç¯éã
- å
³é®æè®:
- ä¸è¦å设APIçå卿§ï¼æ»è¦éªè¯ã
arg_incRef/arg_newRefççä¼¼åçç彿°å¯è½ä¸åå¨ã- è¿åå¼å¿ 须使ç¨ç±»åç¹å®çæé 彿°ï¼èé对象å¼ç¨ã
-
å®è·µåï¼ç®æ³éæ©å¨åéç¯å¢ä¸çå®ç¨ä¸»ä¹
- åºæ¯: æ åç®æ³å¨PikaPythonä¸ä¸å¯è¡ï¼éè¦å¯»æ¾æ¿ä»£æ¹æ¡ã
- çç¥: ä¼å éæ©ç¡®å®å¯è¡çç®æ³ï¼å³ä½¿æ¶é´å¤æåº¦è¾é«ã
- å³çæ¡æ¶:
- è¯ä¼°éå¶: æ£æ¥ç®æ³æ¯å¦ä¾èµä¸æ¯æçç¹æ§ï¼åå ¸ãå¤æè¯æ³çï¼ã
- å¯»æ¾æ¿ä»£: 为é«é£é©ç»ä»¶å¯»æ¾çä»·çç®åå®ç°ã
- æ§è½æè¡¡: å¨åè½æ£ç¡®æ§åæ§è½ä¹é´ï¼éæ©åè ã
- æåæ¡ä¾: ç¨åé循ç¯è®¡æ°æ¿ä»£åå ¸è®¡æ°ï¼è½ç¶O(n²)ä½ä¿è¯ç¨³å®è¿è¡ã
-
å®è·µäºï¼ç±»ååç¼é®çç¥å¤çæ··åæ°æ®ç±»å
-
åºæ¯: éè¦å¨ C 代ç ä¸å¯¹å å«ä¸åæ°æ®ç±»åçå表è¿è¡è®¡æ°æåç»ã
-
çç¥: 使ç¨å¸¦ç±»ååç¼çåç¬¦ä¸²é®æ¥å¤çæ··åæ°æ®ç±»åã
-
å®ç°æ¨¡å¼:
char key[128] = {0}; if (arg_getType(item_arg) == ARG_TYPE_INT) { snprintf(key, sizeof(key), "i_%ld", (long)arg_getInt(item_arg)); } else if (arg_getType(item_arg) == ARG_TYPE_FLOAT) { snprintf(key, sizeof(key), "f_%.6f", arg_getFloat(item_arg)); } else if (arg_getType(item_arg) == ARG_TYPE_STRING) { snprintf(key, sizeof(key), "s_%s", arg_getStr(item_arg)); } -
ä¼å¿: å®ç¾è§£å³ PikaPython åå ¸é®å¿ é¡»æ¯å符串çéå¶ï¼æ¯ææ··åç±»åå¤çã
-
-
å®è·µå ï¼æ¸è¿å¼ç¯å¢éåº
- åºæ¯: 忬¡æ¥è§¦ PikaPython éå¶ï¼å¯¼è´å¤æ¬¡è¯éã
- çç¥: éç¨æ¸è¿å¼æ¹æ³ï¼å å®ç°åºç¡åè½ï¼å鿥ä¼åã
- æ¥éª¤:
- ç¯å¢è®¤ç¥: é¦å æ·±å ¥äºè§£ PikaPython çè¯æ³åéå API éå¶ã
- æå°åå®ç°: 仿ç®åçç®æ³å¼å§ï¼ç¡®ä¿è½ç¨³å®è¿è¡ã
- å¢éä¼å: å¨ä¿è¯åè½æ£ç¡®çåæä¸ï¼éæ¥æ¹è¿æ§è½ã
- è¾¹çæµè¯: ç¹å«å ³æ³¨ç©ºè¾å ¥ãè¾¹çæ¡ä»¶çæåºé®é¢çæ åµã
- å ³é®åå: åè½æ£ç¡®æ§æ°¸è¿ä¼å äºæ§è½ä¼åã
-
å®è·µä¸ï¼ç±»åå®å ¨çæ°æ®æå模å¼
-
åºæ¯: å¨ C 代ç ä¸å¤ç Python å表å ç´ æ¶ï¼éè¦å®å ¨å°æå
intåfloatå¼ã -
çç¥: å»ºç«æ ååçç±»åæ£æ¥åæå模å¼ï¼é¿å ç±»åä¸å¹é é误ã
-
å®ç°æ¨¡å¼:
// æ ååçå ç´ å¤çæ¨¡å¼ pika_float value = 0.0; if (arg_getType(element) == ARG_TYPE_INT) { value = (pika_float)arg_getInt(element); } else if (arg_getType(element) == ARG_TYPE_FLOAT) { value = arg_getFloat(element); } else { // å¤ç䏿¯æçç±»åæè¿åé误 return arg_newNone(); } -
ä¼å¿: ç¡®ä¿ç±»åå®å ¨ï¼é¿å è¿è¡æ¶å´©æºï¼å¹¶æä¾æ¸ æ°çé误å¤çã
-
-
å®è·µå «ï¼è¾¹çæ åµä¼å 设计
-
åºæ¯: å¿è®°å¤ç空å表ãNone å¼çè¾¹çæ åµï¼å¯¼è´è¿è¡æ¶é误ã
-
çç¥: å¨å½æ°å¼å§å¤ä¼å æ£æ¥è¾¹çæ åµï¼ç¡®ä¿æ ¸å¿é»è¾åªå¤çææè¾å ¥ã
-
å®ç°æ¨¡å¼:
// è¾¹çæ åµä¼å å¤ç int len = pikaList_getSize((PikaList*)nums); if (len == 0) { // ç´æ¥è¿åéå½çé»è®¤å¼ return arg_newNone(); // æç©ºå表ç } // ç¶åå¤çæ£å¸¸æ åµ -
ä¼å¿: ç®åæ ¸å¿é»è¾ï¼æé«ä»£ç å¯è¯»æ§å鲿£æ§ã
-
-
å®è·µä¹ï¼æ§è½æµè¯çé离åå
- åºæ¯: åè½æµè¯å¤±è´¥æ¶ä»è¿è¡æ§è½æµè¯ï¼å¯¼è´æ æçæ§è½æ°æ®ã
- çç¥: ä¸¥æ ¼é离åè½éªè¯åæ§è½æµè¯ï¼ç¡®ä¿æ§è½åºå建ç«å¨æ£ç¡®å®ç°ä¹ä¸ã
- 宿½è¦ç¹:
- ææåè½æè¨éè¿ååå¼å§æ§è½æµè¯ã
- 使ç¨ç¸åçè¾å ¥æ°æ®è¿è¡ Python åºçº¿å C æ¨¡åæµè¯ã
- è®°å½è¯¦ç»ç计æ¶ä¿¡æ¯ï¼ä¾¿äºé®é¢è¯æã
- å ³é®æé: æ§è½ä¼åæ°¸è¿ä¸è½çºç²åè½æ£ç¡®æ§ã
8 è¾åºæ ¼å¼å®ä¹
æåæ¶ï¼
[MODULE] <module_name>
[OUTPUT]
<å
³é®è¿è¡è¾åºè¡ï¼EXAMPLE / PERF / SELFTEST>
[END]
ï¼æ¬æä»¶å¯è¿ä»£ä¼åï¼ä½éä¿æç¼å·ä½ç³»ä¸åä¸è¯ä¹æ¥æºï¼ä¸åéå¤å®ä¹ãï¼