├── LICENSE ├── README.md ├── copcode.py ├── csandbox.py ├── frame.py ├── function.py ├── g.py ├── opcode ├── stack.py ├── test.py └── test_files ├── test0.py ├── test1.py ├── test2.py ├── test3.py ├── test4.py ├── test5.py ├── test6.py ├── test7.py ├── test8.py └── test9.py /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSandBox 2 | 这是一个基于 Python 的 Python 沙盒程序. 3 | 只支持单文件进行运行. 4 | 5 | 以支持的功能: 6 | + 基础数据结构 7 | + 字符串 8 | + int 9 | + float 10 | + bool 11 | + 列表 12 | + 字典 13 | + 元组 14 | + 切片 15 | 16 | + 函数 17 | + 位置参数 18 | + 闭包 19 | + 递归 20 | 21 | + 控制语句 22 | + if 23 | + for 24 | + while 25 | + 运算 26 | + 基础四则运算 27 | + 位运算 28 | + 逻辑运算 29 | + 几乎全部的 Python 支持的运算 30 | 31 | 以上足以满足基础的算法编写需求 32 | 33 | 不支持的功能: 34 | + 函数 35 | + 装饰器 36 | + 键传参 37 | 38 | + 类 39 | + 生成器(包括生成器表达式) 40 | + 协程 41 | + 导入包 42 | + 多文件 43 | + 等高级特性 44 | 45 | 如果想要了解更多请去看测试用例. -------------------------------------------------------------------------------- /copcode.py: -------------------------------------------------------------------------------- 1 | from operator import le, lt, ge, gt, eq, ne, is_, is_not, contains, not_ 2 | from function import Function 3 | from frame import new_frame 4 | 5 | frames = [] 6 | 7 | 8 | class OpCode: 9 | cmp_op = (lt, le, eq, ne, gt, ge, lambda a, b: contains(b, a), 10 | lambda a, b: not_(contains(b, a)), is_, is_not) # 支持的比较运算符 11 | 12 | def __init__(self, frame): 13 | self.frame = frame 14 | self.stack = frame.stack 15 | self.co_code = frame.co_code 16 | self.co_consts = frame.co_consts 17 | self.co_cellvars = frame.co_cellvars 18 | self.co_freevars = frame.co_freevars 19 | self.co_consts = frame.co_consts 20 | self.co_name = frame.co_name 21 | self.co_names = frame.co_names 22 | self.co_nlocals = frame.co_nlocals 23 | self.co_argcount = frame.co_argcount 24 | self.global_ = frame.global_ 25 | self.local = frame.local 26 | self.builtin = frame.builtin 27 | self.dict = frame.dict 28 | self.co_varnames = frame.co_varnames 29 | self.blocks = frame.blocks 30 | self.if_return = False 31 | self.opcode_dict = {'1': 'POP_TOP', 32 | '2': 'ROT_TWO', 33 | '3': 'ROT_THREE', 34 | '4': 'DUP_TOP', 35 | '5': 'DUP_TOP_TWO', 36 | '9': 'NOP', 37 | '10': 'UNARY_POSITIVE', 38 | '11': 'UNARY_NEGATIVE', 39 | '12': 'UNARY_NOT', 40 | '15': 'UNARY_INVERT', 41 | '16': 'BINARY_MATRIX_MULTIPLY', 42 | '17': 'INPLACE_MATRIX_MULTIPLY', 43 | '19': 'BINARY_POWER', 44 | '20': 'BINARY_MULTIPLY', 45 | '22': 'BINARY_MODULO', 46 | '23': 'BINARY_ADD', 47 | '24': 'BINARY_SUBTRACT', 48 | '25': 'BINARY_SUBSCR', 49 | '26': 'BINARY_FLOOR_DIVIDE', 50 | '27': 'BINARY_TRUE_DIVIDE', 51 | '28': 'INPLACE_FLOOR_DIVIDE', 52 | '29': 'INPLACE_TRUE_DIVIDE', 53 | '50': 'GET_AITER', 54 | '51': 'GET_ANEXT', 55 | '52': 'BEFORE_ASYNC_WITH', 56 | '55': 'INPLACE_ADD', 57 | '56': 'INPLACE_SUBTRACT', 58 | '57': 'INPLACE_MULTIPLY', 59 | '59': 'INPLACE_MODULO', 60 | '60': 'STORE_SUBSCR', 61 | '61': 'DELETE_SUBSCR', 62 | '62': 'BINARY_LSHIFT', 63 | '63': 'BINARY_RSHIFT', 64 | '64': 'BINARY_AND', 65 | '65': 'BINARY_XOR', 66 | '66': 'BINARY_OR', 67 | '67': 'INPLACE_POWER', 68 | '68': 'GET_ITER', 69 | '69': 'GET_YIELD_FROM_ITER', 70 | '70': 'PRINT_EXPR', 71 | '71': 'LOAD_BUILD_CLASS', 72 | '72': 'YIELD_FROM', 73 | '73': 'GET_AWAITABLE', 74 | '75': 'INPLACE_LSHIFT', 75 | '76': 'INPLACE_RSHIFT', 76 | '77': 'INPLACE_AND', 77 | '78': 'INPLACE_XOR', 78 | '79': 'INPLACE_OR', 79 | '80': 'BREAK_LOOP', 80 | '81': 'WITH_CLEANUP_START', 81 | '82': 'WITH_CLEANUP_FINISH', 82 | '83': 'RETURN_VALUE', 83 | '84': 'IMPORT_STAR', 84 | '85': 'SETUP_ANNOTATIONS', 85 | '86': 'YIELD_VALUE', 86 | '87': 'POP_BLOCK', 87 | '88': 'END_FINALLY', 88 | '89': 'POP_EXCEPT', 89 | '90': 'STORE_NAME', 90 | '91': 'DELETE_NAME', 91 | '92': 'UNPACK_SEQUENCE', 92 | '93': 'FOR_ITER', 93 | '94': 'UNPACK_EX', 94 | '95': 'STORE_ATTR', 95 | '96': 'DELETE_ATTR', 96 | '97': 'STORE_GLOBAL', 97 | '98': 'DELETE_GLOBAL', 98 | '100': 'LOAD_CONST', 99 | '101': 'LOAD_NAME', 100 | '102': 'BUILD_TUPLE', 101 | '103': 'BUILD_LIST', 102 | '104': 'BUILD_SET', 103 | '105': 'BUILD_MAP', 104 | '106': 'LOAD_ATTR', 105 | '107': 'COMPARE_OP', 106 | '108': 'IMPORT_NAME', 107 | '109': 'IMPORT_FROM', 108 | '110': 'JUMP_FORWARD', 109 | '111': 'JUMP_IF_FALSE_OR_POP', 110 | '112': 'JUMP_IF_TRUE_OR_POP', 111 | '113': 'JUMP_ABSOLUTE', 112 | '114': 'POP_JUMP_IF_FALSE', 113 | '115': 'POP_JUMP_IF_TRUE', 114 | '116': 'LOAD_GLOBAL', 115 | '119': 'CONTINUE_LOOP', 116 | '120': 'SETUP_LOOP', 117 | '121': 'SETUP_EXCEPT', 118 | '122': 'SETUP_FINALLY', 119 | '124': 'LOAD_FAST', 120 | '125': 'STORE_FAST', 121 | '126': 'DELETE_FAST', 122 | '127': 'STORE_ANNOTATION', 123 | '130': 'RAISE_VARARGS', 124 | '131': 'CALL_FUNCTION', 125 | '132': 'MAKE_FUNCTION', 126 | '133': 'BUILD_SLICE', 127 | '135': 'LOAD_CLOSURE', 128 | '136': 'LOAD_DEREF', 129 | '137': 'STORE_DEREF', 130 | '138': 'DELETE_DEREF', 131 | '141': 'CALL_FUNCTION_KW', 132 | '142': 'CALL_FUNCTION_EX', 133 | '143': 'SETUP_WITH', 134 | '144': 'EXTENDED_ARG', 135 | '145': 'LIST_APPEND', 136 | '146': 'SET_ADD', 137 | '147': 'MAP_ADD', 138 | '148': 'LOAD_CLASSDEREF', 139 | '149': 'BUILD_LIST_UNPACK', 140 | '150': 'BUILD_MAP_UNPACK', 141 | '151': 'BUILD_MAP_UNPACK_WITH_CALL', 142 | '152': 'BUILD_TUPLE_UNPACK', 143 | '153': 'BUILD_SET_UNPACK', 144 | '154': 'SETUP_ASYNC_WITH', 145 | '155': 'FORMAT_VALUE', 146 | '156': 'BUILD_CONST_KEY_MAP', 147 | '157': 'BUILD_STRING', 148 | '158': 'BUILD_TUPLE_UNPACK_WITH_CALL', 149 | '257': 'EXCEPT_HANDLER'} 150 | 151 | def opcode_1(self, oparg): 152 | """弹出栈顶元素.""" 153 | # define POP_TOP 1 154 | self.stack.pop() 155 | 156 | def opcode_2(self, oparg): 157 | """交换栈顶和第二个的位置.""" 158 | # define ROT_TWO 2 159 | top = self.stack.top() 160 | second = self.stack.second() 161 | self.stack.set_top(second) 162 | self.stack.set_second(top) 163 | 164 | def opcode_3(self, oparg): 165 | """栈顶三个元素之间交换.""" 166 | # define ROT_THREE 3 167 | top = self.stack.pop() 168 | second = self.stack.pop() 169 | third = self.stack.pop() 170 | self.stack.push(top) 171 | self.stack.push(third) 172 | self.stack.push(second) 173 | 174 | def opcode_4(self, oparg): 175 | """复制栈顶并压入栈.""" 176 | # define DUP_TOP 4 177 | top = self.stack.top() 178 | self.stack.push(top) 179 | 180 | def opcode_5(self, oparg): 181 | """复制栈顶两个元素并压入栈, 顺序不变.""" 182 | # define DUP_TOP_TWO 5 183 | top = self.stack.top() 184 | second = self.stack.second() 185 | self.stack.push(second) 186 | self.stack.push(top) 187 | 188 | def opcode_9(self, oparg): 189 | # define NOP 9 190 | code = "NOP" 191 | raise RuntimeError("使用到未实现的字节码:"+code) 192 | 193 | def opcode_10(self, oparg): 194 | 195 | # define UNARY_POSITIVE 10 196 | code = "UNARY_POSITIVE" 197 | raise RuntimeError("使用到未实现的字节码:"+code) 198 | 199 | def opcode_11(self, oparg): 200 | """针对 -a 运算的字节码.""" 201 | # define UNARY_NEGATIVE 11 202 | value = self.stack.pop() 203 | res = -value 204 | self.stack.push(res) 205 | 206 | def opcode_12(self, oparg): 207 | # define UNARY_NOT 12 208 | code = "UNARY_NOT" 209 | raise RuntimeError("使用到未实现的字节码:"+code) 210 | 211 | def opcode_15(self, oparg): 212 | # define UNARY_INVERT 15 213 | value = self.stack.pop() 214 | res = ~value 215 | self.stack.push(res) 216 | 217 | def opcode_16(self, oparg): 218 | # define BINARY_MATRIX_MULTIPLY 16 219 | code = "BINARY_MATRIX_MULTIPLY" 220 | raise RuntimeError("使用到未实现的字节码:"+code) 221 | 222 | def opcode_17(self, oparg): 223 | # define INPLACE_MATRIX_MULTIPLY 17 224 | code = "INPLACE_MATRIX_MULTIPLY" 225 | raise RuntimeError("使用到未实现的字节码:"+code) 226 | 227 | def opcode_19(self, oparg): 228 | """乘方运算.""" 229 | # define BINARY_POWER 19 230 | right = self.stack.pop() 231 | left = self.stack.pop() 232 | res = left ** right 233 | self.stack.push(res) 234 | 235 | def opcode_20(self, oparg): 236 | """乘法运算.""" 237 | # define BINARY_MULTIPLY 20 238 | rigth = self.stack.pop() 239 | left = self.stack.pop() 240 | res = left * rigth 241 | self.stack.push(res) 242 | 243 | def opcode_22(self, oparg): 244 | """取模运算.""" 245 | # define BINARY_MODULO 22 246 | divisor = self.stack.pop() 247 | dividend = self.stack.pop() 248 | res = dividend % divisor 249 | self.stack.push(res) 250 | 251 | def opcode_23(self, oparg): 252 | """加法运算.""" 253 | # define BINARY_ADD 23 254 | right = self.stack.pop() 255 | left = self.stack.pop() 256 | res = left + right 257 | self.stack.push(res) 258 | 259 | def opcode_24(self, oparg): 260 | """减法运算.""" 261 | # define BINARY_SUBTRACT 24 262 | right = self.stack.pop() 263 | left = self.stack.pop() 264 | res = left - right 265 | self.stack.push(res) 266 | 267 | def opcode_25(self, oparg): 268 | """如果 index 是数字的话就是按照索引取值,如果是 slice 就是取子序列.""" 269 | # define BINARY_SUBSCR 25 270 | index = self.stack.pop() 271 | list_ = self.stack.pop() 272 | value = list_[index] 273 | self.stack.push(value) 274 | 275 | def opcode_26(self, oparg): 276 | """除法运算.""" 277 | # define BINARY_FLOOR_DIVIDE 26 278 | right = self.stack.pop() 279 | left = self.stack.pop() 280 | res = left // right 281 | self.stack.push(res) 282 | 283 | def opcode_27(self, oparg): 284 | """真除法运算.""" 285 | # define BINARY_TRUE_DIVIDE 27 286 | right = self.stack.pop() 287 | left = self.stack.pop() 288 | res = left / right 289 | self.stack.push(res) 290 | 291 | def opcode_28(self, oparg): 292 | """就地除法运算.""" 293 | # define INPLACE_FLOOR_DIVIDE 28 294 | right = self.stack.pop() 295 | left = self.stack.pop() 296 | left //= right 297 | self.stack.push(left) 298 | 299 | def opcode_29(self, oparg): 300 | """就地真除法运算.""" 301 | # define INPLACE_TRUE_DIVIDE 29 302 | right = self.stack.pop() 303 | left = self.stack.pop() 304 | left /= right 305 | self.stack.push(left) 306 | 307 | def opcode_50(self, oparg): 308 | # define GET_AITER 50 309 | code = "GET_AITER" 310 | raise RuntimeError("使用到未实现的字节码:"+code) 311 | 312 | def opcode_51(self, oparg): 313 | # define GET_ANEXT 51 314 | code = "GET_ANEXT" 315 | raise RuntimeError("使用到未实现的字节码:"+code) 316 | 317 | def opcode_52(self, oparg): 318 | 319 | # define BEFORE_ASYNC_WITH 52 320 | code = "BEFORE_ASYNC_WITH" 321 | raise RuntimeError("使用到未实现的字节码:"+code) 322 | 323 | def opcode_55(self, oparg): 324 | """就地加法运算.""" 325 | # define INPLACE_ADD 55 326 | right = self.stack.pop() 327 | left = self.stack.pop() 328 | left += right 329 | self.stack.push(left) 330 | 331 | def opcode_56(self, oparg): 332 | """就地减法运算.""" 333 | # define INPLACE_SUBTRACT 56 334 | right = self.stack.pop() 335 | left = self.stack.pop() 336 | left -= right 337 | self.stack.push(left) 338 | 339 | def opcode_57(self, oparg): 340 | """就地乘法运算.""" 341 | # define INPLACE_MULTIPLY 57 342 | right = self.stack.pop() 343 | left = self.stack.pop() 344 | left *= right 345 | self.stack.push(left) 346 | 347 | def opcode_59(self, oparg): 348 | """就地取模运算.""" 349 | # define INPLACE_MODULO 59 350 | right = self.stack.pop() 351 | left = self.stack.pop() 352 | left %= right 353 | self.stack.push(left) 354 | 355 | def opcode_60(self, oparg): 356 | """将一个序列插入另外一个序列 a[1:2] = [1,2,3,4,5,6].""" 357 | # define STORE_SUBSCR 60 358 | s = self.stack.pop() 359 | x = self.stack.pop() 360 | other_list = self.stack.pop() 361 | x[s] = other_list 362 | 363 | def opcode_61(self, oparg): 364 | # define DELETE_SUBSCR 61 365 | code = "DELETE_SUBSCR" 366 | raise RuntimeError("使用到未实现的字节码:"+code) 367 | 368 | def opcode_62(self, oparg): 369 | """左移运算""" 370 | # define BINARY_LSHIFT 62 371 | right = self.stack.pop() 372 | left = self.stack.pop() 373 | res = left << right 374 | self.stack.push(res) 375 | 376 | def opcode_63(self, oparg): 377 | """右移运算""" 378 | # define BINARY_RSHIFT 63 379 | rigth = self.stack.pop() 380 | left = self.stack.pop() 381 | res = left >> rigth 382 | self.stack.push(res) 383 | 384 | def opcode_64(self, oparg): 385 | """与运算""" 386 | # define BINARY_AND 64 387 | rigth = self.stack.pop() 388 | left = self.stack.pop() 389 | res = left & rigth 390 | self.stack.push(res) 391 | 392 | def opcode_65(self, oparg): 393 | """异或运算""" 394 | # define BINARY_XOR 65 395 | rigth = self.stack.pop() 396 | left = self.stack.pop() 397 | res = left ^ rigth 398 | self.stack.push(res) 399 | 400 | def opcode_66(self, oparg): 401 | """或运算""" 402 | # define BINARY_OR 66 403 | rigth = self.stack.pop() 404 | left = self.stack.pop() 405 | res = left | rigth 406 | self.stack.push(res) 407 | 408 | def opcode_67(self, oparg): 409 | """就地乘方运算.""" 410 | # define INPLACE_POWER 67 411 | right = self.stack.pop() 412 | left = self.stack.pop() 413 | left **= right 414 | self.stack.push(left) 415 | 416 | def opcode_68(self, oparg): 417 | """获取可迭代对象的迭代器.""" 418 | # define GET_ITER 68 419 | a = self.stack.pop() 420 | it = iter(a) 421 | self.stack.push(it) 422 | 423 | def opcode_69(self, oparg): 424 | # define GET_YIELD_FROM_ITER 69 425 | code = "GET_YIELD_FROM_ITER" 426 | raise RuntimeError("使用到未实现的字节码:"+code) 427 | 428 | def opcode_70(self, oparg): 429 | # define PRINT_EXPR 70 430 | code = "PRINT_EXPR" 431 | raise RuntimeError("使用到未实现的字节码:"+code) 432 | 433 | def opcode_71(self, oparg): 434 | # define LOAD_BUILD_CLASS 71 435 | # code = "LOAD_BUILD_CLASS" 436 | # raise RuntimeError("使用到未实现的字节码:"+code) 437 | print(self.stack) 438 | def opcode_72(self, oparg): 439 | # define YIELD_FROM 72 440 | code = "YIELD_FROM" 441 | raise RuntimeError("使用到未实现的字节码:"+code) 442 | 443 | def opcode_73(self, oparg): 444 | # define GET_AWAITABLE 73 445 | code = "GET_AWAITABLE" 446 | raise RuntimeError("使用到未实现的字节码:"+code) 447 | 448 | def opcode_75(self, oparg): 449 | # define INPLACE_LSHIFT 75 450 | code = "INPLACE_LSHIFT" 451 | raise RuntimeError("使用到未实现的字节码:"+code) 452 | 453 | def opcode_76(self, oparg): 454 | # define INPLACE_RSHIFT 76 455 | code = "INPLACE_RSHIFT" 456 | raise RuntimeError("使用到未实现的字节码:"+code) 457 | 458 | def opcode_77(self, oparg): 459 | """按位与运算""" 460 | # define INPLACE_AND 77 461 | right = self.stack.pop() 462 | left = self.stack.pop() 463 | left &= right 464 | self.stack.push(left) 465 | 466 | def opcode_78(self, oparg): 467 | # define INPLACE_XOR 78 468 | code = "INPLACE_XOR" 469 | raise RuntimeError("使用到未实现的字节码:"+code) 470 | 471 | def opcode_79(self, oparg): 472 | """按位或运算""" 473 | # define INPLACE_OR 79 474 | right = self.stack.pop() 475 | left = self.stack.pop() 476 | left |= right 477 | self.stack.push(left) 478 | 479 | def opcode_80(self, oparg): 480 | """循环结束.""" 481 | # define BREAK_LOOP 80 482 | self.frame.index = self.forend 483 | self.stack.pop() 484 | 485 | def opcode_81(self, oparg): 486 | 487 | # define WITH_CLEANUP_START 81 488 | code = "WITH_CLEANUP_START" 489 | raise RuntimeError("使用到未实现的字节码:"+code) 490 | 491 | def opcode_82(self, oparg): 492 | # define WITH_CLEANUP_FINISH 82 493 | code = "WITH_CLEANUP_FINISH" 494 | raise RuntimeError("使用到未实现的字节码:"+code) 495 | 496 | def opcode_83(self, oparg): 497 | """返回值.""" 498 | # define RETURN_VALUE 83 499 | value = self.stack.pop() 500 | index = frames.index(self.frame) 501 | if (index != 0): 502 | frame = frames[index-1] 503 | frame.stack.push(value) 504 | self.if_return = True 505 | else: 506 | exit(0) 507 | 508 | def opcode_84(self, oparg): 509 | # define IMPORT_STAR 84 510 | code = "IMPORT_STAR" 511 | raise RuntimeError("使用到未实现的字节码:"+code) 512 | 513 | def opcode_85(self, oparg): 514 | # define SETUP_ANNOTATIONS 85 515 | code = "SETUP_ANNOTATIONS" 516 | raise RuntimeError("使用到未实现的字节码:"+code) 517 | 518 | def opcode_86(self, oparg): 519 | # define YIELD_VALUE 86 520 | code = "YIELD_VALUE" 521 | raise RuntimeError("使用到未实现的字节码:"+code) 522 | 523 | def opcode_87(self, oparg): 524 | """这个我只针对了 for 进行的处理.""" 525 | # define POP_BLOCK 87 526 | p = self.blocks.pop() 527 | index = len(self.stack) 528 | while index > p: 529 | self.stack.pop() 530 | index -= 1 531 | 532 | def opcode_88(self, oparg): 533 | # define END_FINALLY 88 534 | code = "END_FINALLY" 535 | raise RuntimeError("使用到未实现的字节码:"+code) 536 | 537 | def opcode_89(self, oparg): 538 | # define POP_EXCEPT 89 539 | code = "POP_EXCEPT" 540 | raise RuntimeError("使用到未实现的字节码:"+code) 541 | 542 | def opcode_90(self, oparg): 543 | """给相应对象设置名字.""" 544 | # define STORE_NAME 90 545 | value = self.stack.pop() 546 | name = self.co_names[oparg] 547 | self.local[name] = value 548 | 549 | def opcode_91(self, oparg): 550 | # define DELETE_NAME 91 551 | code = "DELETE_NAME" 552 | raise RuntimeError("使用到未实现的字节码:"+code) 553 | 554 | def opcode_92(self, oparg): 555 | """从堆栈中获取一个可迭代的对象然后对它进行拆包然后倒序压入栈""" 556 | # define UNPACK_SEQUENCE 92 557 | sequence = self.stack.pop() 558 | for item in sequence[::-1]: 559 | self.stack.push(item) 560 | 561 | def opcode_93(self, oparg): 562 | # define FOR_ITER 93 563 | it = self.stack.top() 564 | try: 565 | value = next(it) 566 | self.stack.push(value) 567 | except StopIteration: 568 | self.stack.pop() 569 | self.frame.index += oparg 570 | 571 | def opcode_94(self, oparg): 572 | # define UNPACK_EX 94 573 | code = "UNPACK_EX" 574 | raise RuntimeError("使用到未实现的字节码:"+code) 575 | 576 | def opcode_95(self, oparg): 577 | # define STORE_ATTR 95 578 | code = "STORE_ATTR" 579 | raise RuntimeError("使用到未实现的字节码:"+code) 580 | 581 | def opcode_96(self, oparg): 582 | # define DELETE_ATTR 96 583 | code = "DELETE_ATTR" 584 | raise RuntimeError("使用到未实现的字节码:"+code) 585 | 586 | def opcode_97(self, oparg): 587 | # define STORE_GLOBAL 97 588 | name = self.co_names[oparg] 589 | value = self.stack.pop() 590 | self.global_[name] = value 591 | 592 | def opcode_98(self, oparg): 593 | # define DELETE_GLOBAL 98 594 | code = "DELETE_GLOBAL" 595 | raise RuntimeError("使用到未实现的字节码:"+code) 596 | 597 | def opcode_100(self, oparg): 598 | # define LOAD_CONST 100 599 | value = self.co_consts[oparg] 600 | self.stack.push(value) 601 | 602 | def opcode_101(self, oparg): 603 | # define LOAD_NAME 101 604 | name = self.co_names[oparg] 605 | value = None 606 | if name in self.local: 607 | value = self.local[name] 608 | if not value: 609 | if name in self.global_: 610 | value = self.global_[name] 611 | if not value: 612 | if name in self.builtin: 613 | value = self.builtin[name] 614 | self.stack.push(value) 615 | 616 | def opcode_102(self, oparg): 617 | # define BUILD_TUPLE 102 618 | list_ = [] 619 | for _ in range(oparg): 620 | a = self.stack.pop() 621 | list_.append(a) 622 | res = tuple(list_[::-1]) 623 | self.stack.push(res) 624 | 625 | def opcode_103(self, oparg): 626 | # define BUILD_LIST 103 627 | list_ = [] 628 | for i in range(oparg): 629 | value = self.stack.pop() 630 | list_.append(value) 631 | self.stack.push(list_[::-1]) 632 | 633 | def opcode_104(self, oparg): 634 | # define BUILD_SET 104 635 | code = "BUILD_SET" 636 | raise RuntimeError("使用到未实现的字节码:"+code) 637 | 638 | def opcode_105(self, oparg): 639 | # define BUILD_MAP 105 640 | res = {} 641 | values = [] 642 | keys = [] 643 | for _ in range(oparg): 644 | values.append(self.stack.pop()) 645 | keys.append(self.stack.pop()) 646 | for key, value in zip(keys[::-1], values[::-1]): 647 | res[key] = value 648 | self.stack.push(res) 649 | 650 | def opcode_106(self, oparg): 651 | """屏蔽所以 LOAD_ATTR 中以 __ 开头的并且不是 __init__ 的所有属性""" 652 | # define LOAD_ATTR 106 653 | c = self.stack.pop() 654 | name = self.co_names[oparg] 655 | assert not (name.startswith("__") and name != "__init__") 656 | res = getattr(c, name) 657 | self.stack.push(res) 658 | 659 | def opcode_107(self, oparg): 660 | # define COMPARE_OP 107 661 | right = self.stack.pop() 662 | left = self.stack.pop() 663 | cmp_ = self.cmp_op[oparg] 664 | res = cmp_(left, right) 665 | self.stack.push(res) 666 | 667 | def opcode_108(self, oparg): 668 | # define IMPORT_NAME 108 669 | code = "IMPORT_NAME" 670 | raise RuntimeError("使用到未实现的字节码:"+code) 671 | 672 | def opcode_109(self, oparg): 673 | # define IMPORT_FROM 109 674 | code = "IMPORT_FROM" 675 | raise RuntimeError("使用到未实现的字节码:"+code) 676 | 677 | def opcode_110(self, oparg): 678 | # define JUMP_FORWARD 110 679 | self.frame.index += oparg 680 | 681 | def opcode_111(self, oparg): 682 | # define JUMP_IF_FALSE_OR_POP 111 683 | cond = self.stack.top() 684 | if cond is True: 685 | self.stack.pop() 686 | else: 687 | self.frame.index = oparg 688 | 689 | def opcode_112(self, oparg): 690 | # define JUMP_IF_TRUE_OR_POP 112 691 | cond = self.stack.top() 692 | if cond is True: 693 | self.frame.index = oparg 694 | else: 695 | self.stack.pop() 696 | 697 | def opcode_113(self, oparg): 698 | # define JUMP_ABSOLUTE 113 699 | self.frame.index = oparg 700 | 701 | def opcode_114(self, oparg): 702 | # define POP_JUMP_IF_FALSE 114 703 | a = self.stack.pop() 704 | if a: 705 | pass 706 | else: 707 | self.frame.index = oparg 708 | 709 | def opcode_115(self, oparg): 710 | # define POP_JUMP_IF_TRUE 115 711 | a = self.stack.pop() 712 | if a: 713 | self.frame.index = oparg 714 | 715 | def opcode_116(self, oparg): 716 | # define LOAD_GLOBAL 116 717 | name = self.co_names[oparg] 718 | if name in self.global_: 719 | value = self.global_[name] 720 | else: 721 | value = self.builtin[name] 722 | self.stack.push(value) 723 | 724 | def opcode_119(self, oparg): 725 | # define CONTINUE_LOOP 119 726 | code = "CONTINUE_LOOP" 727 | raise RuntimeError("使用到未实现的字节码:"+code) 728 | 729 | def opcode_120(self, oparg): 730 | # define SETUP_LOOP 120 731 | p = len(self.stack) 732 | self.blocks.push(p) # 将当前运行时栈长度压入 blocks 栈 733 | self.forend = self.frame.index + oparg 734 | 735 | def opcode_121(self, oparg): 736 | # define SETUP_EXCEPT 121 737 | code = "SETUP_EXCEPT" 738 | raise RuntimeError("使用到未实现的字节码:"+code) 739 | 740 | def opcode_122(self, oparg): 741 | # define SETUP_FINALLY 122 742 | code = "SETUP_FINALLY" 743 | raise RuntimeError("使用到未实现的字节码:"+code) 744 | 745 | def opcode_124(self, oparg): 746 | # define LOAD_FAST 124 747 | name = self.co_varnames[oparg] 748 | try: 749 | value = self.dict[self.co_varnames[oparg]] 750 | except KeyError as e: 751 | raise TypeError("missing " + name) 752 | self.stack.push(value) 753 | 754 | def opcode_125(self, oparg): 755 | # define STORE_FAST 125 756 | name = self.co_varnames[oparg] 757 | value = self.stack.pop() 758 | self.dict[name] = value 759 | 760 | def opcode_126(self, oparg): 761 | # define DELETE_FAST 126 762 | code = "DELETE_FAST" 763 | raise RuntimeError("使用到未实现的字节码:"+code) 764 | 765 | def opcode_127(self, oparg): 766 | # define STORE_ANNOTATION 127 767 | code = "STORE_ANNOTATION" 768 | raise RuntimeError("使用到未实现的字节码:"+code) 769 | 770 | def opcode_130(self, oparg): 771 | # define RAISE_VARARGS 130 772 | code = "RAISE_VARARGS" 773 | raise RuntimeError("使用到未实现的字节码:"+code) 774 | 775 | def opcode_131(self, oparg): 776 | # define CALL_FUNCTION 131 777 | args = [] 778 | 779 | for _ in range(oparg): 780 | args.append(self.stack.pop()) 781 | 782 | func = self.stack.pop() 783 | if callable(func): 784 | res = func(*args[::-1]) 785 | self.stack.push(res) 786 | elif(isinstance(func, Function)): 787 | frame = new_frame(func) 788 | if oparg > frame.co_argcount: 789 | raise TypeError( 790 | f"{frame.co_name}() takes {frame.co_argcount} positional \ 791 | arguments but {oparg} were given") 792 | 793 | if oparg < frame.co_argcount: 794 | raise TypeError( 795 | f"{frame.co_name}() missing {frame.co_argcount - oparg} \ 796 | required positional arguments: " 797 | + ",".join(frame.co_varnames[oparg:])) 798 | 799 | for name, value in zip(func.varnames, args[::-1]): 800 | frame.dict[name] = value 801 | 802 | frames.append(frame) 803 | run(frame) 804 | frames.pop() 805 | else: 806 | raise RuntimeError("有些事情没有考虑到") 807 | 808 | def opcode_132(self, oparg): 809 | # define MAKE_FUNCTION 132 810 | name = self.stack.pop() 811 | mycode = self.stack.pop() 812 | f = Function(name, mycode) 813 | for i in f.freevars: 814 | f.dict[i] = self.dict[i] 815 | self.stack.push(f) 816 | 817 | def opcode_133(self, oparg): 818 | # define BUILD_SLICE 133 819 | args = [] 820 | for _ in range(oparg): 821 | args.append(self.stack.pop()) 822 | value = slice(*args[::-1]) 823 | self.stack.push(value) 824 | 825 | def opcode_135(self, oparg): 826 | # define LOAD_CLOSURE 135 827 | key = self.co_cellvars[oparg] 828 | value = self.dict[key] 829 | self.stack.push(value) 830 | 831 | def opcode_136(self, oparg): 832 | # define LOAD_DEREF 136 833 | cell = self.co_freevars[oparg] 834 | value = self.dict[cell] 835 | self.stack.push(value) 836 | 837 | def opcode_137(self, oparg): 838 | # define STORE_DEREF 137 839 | value = self.stack.pop() 840 | key = self.co_cellvars[oparg] 841 | self.dict[key] = value 842 | 843 | def opcode_138(self, oparg): 844 | # define DELETE_DEREF 138 845 | code = "DELETE_DEREF" 846 | raise RuntimeError("使用到未实现的字节码:"+code) 847 | 848 | def opcode_141(self, oparg): 849 | # define CALL_FUNCTION_KW 141 850 | code = "CALL_FUNCTION_KW" 851 | raise RuntimeError("使用到未实现的字节码:"+code) 852 | 853 | def opcode_142(self, oparg): 854 | # define CALL_FUNCTION_EX 142 855 | code = "CALL_FUNCTION_EX" 856 | raise RuntimeError("使用到未实现的字节码:"+code) 857 | 858 | def opcode_143(self, oparg): 859 | # define SETUP_WITH 143 860 | code = "SETUP_WITH" 861 | raise RuntimeError("使用到未实现的字节码:"+code) 862 | 863 | def opcode_144(self, oparg): 864 | """计算下一条字节码的参数""" 865 | # define EXTENDED_ARG 144 866 | oldoparg = oparg 867 | oparg = self.frame.co_code[self.frame.index+1] 868 | oparg |= oldoparg << 8 869 | self.frame.co_code[self.frame.index+1] = oparg 870 | 871 | def opcode_145(self, oparg): 872 | # define LIST_APPEND 145 873 | v = self.stack.pop() 874 | list_ = self.stack.peek(oparg) 875 | list_.append(v) 876 | 877 | def opcode_146(self, oparg): 878 | # define SET_ADD 146 879 | code = "SET_ADD" 880 | raise RuntimeError("使用到未实现的字节码:"+code) 881 | 882 | def opcode_147(self, oparg): 883 | # define MAP_ADD 147 884 | key = self.stack.pop() 885 | value = self.stack.pop() 886 | map_ = self.stack.peek(oparg) 887 | map_[key] = value 888 | 889 | def opcode_148(self, oparg): 890 | # define LOAD_CLASSDEREF 148 891 | code = "LOAD_CLASSDEREF" 892 | raise RuntimeError("使用到未实现的字节码:"+code) 893 | 894 | def opcode_149(self, oparg): 895 | # define BUILD_LIST_UNPACK 149 896 | code = "BUILD_LIST_UNPACK" 897 | raise RuntimeError("使用到未实现的字节码:"+code) 898 | 899 | def opcode_150(self, oparg): 900 | # define BUILD_MAP_UNPACK 150 901 | code = "BUILD_MAP_UNPACK" 902 | raise RuntimeError("使用到未实现的字节码:"+code) 903 | 904 | def opcode_151(self, oparg): 905 | # define BUILD_MAP_UNPACK_WITH_CALL 151 906 | code = "BUILD_MAP_UNPACK_WITH_CALL" 907 | raise RuntimeError("使用到未实现的字节码:"+code) 908 | 909 | def opcode_152(self, oparg): 910 | # define BUILD_TUPLE_UNPACK 152 911 | code = "BUILD_TUPLE_UNPACK" 912 | raise RuntimeError("使用到未实现的字节码:"+code) 913 | 914 | def opcode_153(self, oparg): 915 | # define BUILD_SET_UNPACK 153 916 | code = "BUILD_SET_UNPACK" 917 | raise RuntimeError("使用到未实现的字节码:"+code) 918 | 919 | def opcode_154(self, oparg): 920 | # define SETUP_ASYNC_WITH 154 921 | code = "SETUP_ASYNC_WITH" 922 | raise RuntimeError("使用到未实现的字节码:"+code) 923 | 924 | def opcode_155(self, oparg): 925 | # define FORMAT_VALUE 155 926 | code = "FORMAT_VALUE" 927 | raise RuntimeError("使用到未实现的字节码:"+code) 928 | 929 | def opcode_156(self, oparg): 930 | # define BUILD_CONST_KEY_MAP 156 931 | keys = self.stack.pop() 932 | values = [] 933 | for _ in range(oparg): 934 | t = self.stack.pop() 935 | values.append(t) 936 | values = values[::-1] 937 | res = dict(zip(keys, values)) 938 | self.stack.push(res) 939 | 940 | def opcode_157(self, oparg): 941 | # define BUILD_STRING 157 942 | code = "BUILD_STRING" 943 | raise RuntimeError("使用到未实现的字节码:"+code) 944 | 945 | def opcode_158(self, oparg): 946 | # define BUILD_TUPLE_UNPACK_WITH_CALL 158 947 | code = "BUILD_TUPLE_UNPACK_WITH_CALL" 948 | raise RuntimeError("使用到未实现的字节码:"+code) 949 | 950 | def opcode_257(self, oparg): 951 | # define EXCEPT_HANDLER 25 952 | code = "EXCEPT_HANDLER" 953 | raise RuntimeError("使用到未实现的字节码:"+code) 954 | 955 | 956 | def run(f): 957 | run_code = OpCode(f) 958 | co_code = f.co_code 959 | while True: 960 | code = str(co_code[f.index]) 961 | oparg = int(co_code[f.index+1]) 962 | f.index += 2 963 | # import time 964 | # time.sleep(0.2) 965 | # print("下一个字节码的地址是",f.index) 966 | # print(run_code.opcode_dict[code]," ",oparg) 967 | func = getattr(run_code, "opcode_"+code) 968 | if func: 969 | func(oparg) 970 | if f.index == len(co_code) or run_code.if_return is True: 971 | break 972 | -------------------------------------------------------------------------------- /csandbox.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from copcode import (Function, new_frame, frames, run) 4 | 5 | 6 | def init(): 7 | assert len(sys.argv) == 2 and sys.argv[1].endswith(".py") 8 | source = open(sys.argv[1]).read() 9 | co = compile(source, sys.argv[1], 'exec') 10 | fun = Function(sys.argv[1], co) 11 | frame = new_frame(fun) 12 | return frame 13 | 14 | 15 | def main(): 16 | frame = init() 17 | frames.append(frame) 18 | run(frame) 19 | frames.pop() 20 | 21 | 22 | if __name__ == '__main__': 23 | main() 24 | -------------------------------------------------------------------------------- /frame.py: -------------------------------------------------------------------------------- 1 | from stack import stack 2 | from g import builtin, global_ 3 | import copy 4 | 5 | 6 | class MyFrame: 7 | def __init__(self, co): 8 | """dict 是保存 局部变量的,不要误认为是 f.local 了 9 | 它在新的 frame 中和 f.global 是相同的. 10 | 不要问我为什么这样处理因为 Python 源码的实现也是这样处理的.""" 11 | self.co_consts = co.consts 12 | self.co_cellvars = co.cellvars 13 | self.co_freevars = co.freevars 14 | self.co_name = co.name 15 | self.co_names = co.names 16 | self.co_nlocals = co.nlocals 17 | self.co_argcount = co.argcount 18 | self.co_varnames = co.varnames 19 | self.stack = stack(size=co.stacksize) 20 | self.global_ = None 21 | self.local = None 22 | self.bulitin = None 23 | self.dict = copy.deepcopy(co.dict) 24 | self.index = None 25 | self.co_code = self.code_to_int(co.code) 26 | self.blocks = stack(size=20) # python 中块级操作的堆栈.方便运行时堆栈的恢复 27 | 28 | def code_to_int(self, code): 29 | """将 co.co_code 中的 bytes 转为 [int].""" 30 | return [int(x) for x in code] 31 | 32 | 33 | def new_frame(co_code): 34 | f = MyFrame(co_code) 35 | f.global_ = global_ 36 | f.local = global_ 37 | f.builtin = builtin 38 | f.index = 0 39 | return f 40 | -------------------------------------------------------------------------------- /function.py: -------------------------------------------------------------------------------- 1 | class Function: 2 | def __init__(self, name, co_code): 3 | self.name = name 4 | self.code = co_code.co_code 5 | self.consts = co_code.co_consts 6 | self.cellvars = co_code.co_cellvars 7 | self.freevars = co_code.co_freevars 8 | self.names = co_code.co_names 9 | self.nlocals = co_code.co_nlocals 10 | self.argcount = co_code.co_argcount 11 | self.varnames = co_code.co_varnames 12 | self.stacksize = co_code.co_stacksize 13 | self.dict = {} 14 | 15 | def __repr__(self): 16 | return f"" 17 | -------------------------------------------------------------------------------- /g.py: -------------------------------------------------------------------------------- 1 | global_ = {} 2 | builtin = {"print": print, 3 | "max": max, 4 | "sum": sum, 5 | "len": len, 6 | "range": range, 7 | 'hash': hash, 8 | "__name__": "__main__", 9 | "abs": abs, 10 | "all": all, 11 | "any": any, 12 | "bin": bin, 13 | "chr": chr, 14 | "divmod": divmod, 15 | "format": format, 16 | "hex": hex, 17 | "input": input, 18 | "iter": iter, 19 | "len": len, 20 | "max": max, 21 | "min": min, 22 | "next": next, 23 | "oct": oct, 24 | "ord": ord, 25 | "pow": pow, 26 | "repr": repr, 27 | "round": round, 28 | "sorted": sorted, 29 | "None": None, 30 | "False": False, 31 | "True": True, 32 | "bool": bool, 33 | "bytes": bytes, 34 | "complex": complex, 35 | "dict": dict, 36 | "enumerate": enumerate, 37 | "filter": filter, 38 | "float": float, 39 | "frozenset": frozenset, 40 | "int": int, 41 | "list": list, 42 | "map": map, 43 | "set": set, 44 | "slice": slice, 45 | "str": str, 46 | "zip": zip, 47 | "copyright": "来自于copie的沙盒" 48 | } 49 | -------------------------------------------------------------------------------- /opcode: -------------------------------------------------------------------------------- 1 | # Python3.6.5 的字节码 2 | #define POP_TOP 1 3 | #define ROT_TWO 2 4 | #define ROT_THREE 3 5 | #define DUP_TOP 4 6 | #define DUP_TOP_TWO 5 7 | #define NOP 9 8 | #define UNARY_POSITIVE 10 9 | #define UNARY_NEGATIVE 11 10 | #define UNARY_NOT 12 11 | #define UNARY_INVERT 15 12 | #define BINARY_MATRIX_MULTIPLY 16 13 | #define INPLACE_MATRIX_MULTIPLY 17 14 | #define BINARY_POWER 19 15 | #define BINARY_MULTIPLY 20 16 | #define BINARY_MODULO 22 17 | #define BINARY_ADD 23 18 | #define BINARY_SUBTRACT 24 19 | #define BINARY_SUBSCR 25 20 | #define BINARY_FLOOR_DIVIDE 26 21 | #define BINARY_TRUE_DIVIDE 27 22 | #define INPLACE_FLOOR_DIVIDE 28 23 | #define INPLACE_TRUE_DIVIDE 29 24 | #define GET_AITER 50 25 | #define GET_ANEXT 51 26 | #define BEFORE_ASYNC_WITH 52 27 | #define INPLACE_ADD 55 28 | #define INPLACE_SUBTRACT 56 29 | #define INPLACE_MULTIPLY 57 30 | #define INPLACE_MODULO 59 31 | #define STORE_SUBSCR 60 32 | #define DELETE_SUBSCR 61 33 | #define BINARY_LSHIFT 62 34 | #define BINARY_RSHIFT 63 35 | #define BINARY_AND 64 36 | #define BINARY_XOR 65 37 | #define BINARY_OR 66 38 | #define INPLACE_POWER 67 39 | #define GET_ITER 68 40 | #define GET_YIELD_FROM_ITER 69 41 | #define PRINT_EXPR 70 42 | #define LOAD_BUILD_CLASS 71 43 | #define YIELD_FROM 72 44 | #define GET_AWAITABLE 73 45 | #define INPLACE_LSHIFT 75 46 | #define INPLACE_RSHIFT 76 47 | #define INPLACE_AND 77 48 | #define INPLACE_XOR 78 49 | #define INPLACE_OR 79 50 | #define BREAK_LOOP 80 51 | #define WITH_CLEANUP_START 81 52 | #define WITH_CLEANUP_FINISH 82 53 | #define RETURN_VALUE 83 54 | #define IMPORT_STAR 84 55 | #define SETUP_ANNOTATIONS 85 56 | #define YIELD_VALUE 86 57 | #define POP_BLOCK 87 58 | #define END_FINALLY 88 59 | #define POP_EXCEPT 89 60 | #define HAVE_ARGUMENT 90 61 | #define STORE_NAME 90 62 | #define DELETE_NAME 91 63 | #define UNPACK_SEQUENCE 92 64 | #define FOR_ITER 93 65 | #define UNPACK_EX 94 66 | #define STORE_ATTR 95 67 | #define DELETE_ATTR 96 68 | #define STORE_GLOBAL 97 69 | #define DELETE_GLOBAL 98 70 | #define LOAD_CONST 100 71 | #define LOAD_NAME 101 72 | #define BUILD_TUPLE 102 73 | #define BUILD_LIST 103 74 | #define BUILD_SET 104 75 | #define BUILD_MAP 105 76 | #define LOAD_ATTR 106 77 | #define COMPARE_OP 107 78 | #define IMPORT_NAME 108 79 | #define IMPORT_FROM 109 80 | #define JUMP_FORWARD 110 81 | #define JUMP_IF_FALSE_OR_POP 111 82 | #define JUMP_IF_TRUE_OR_POP 112 83 | #define JUMP_ABSOLUTE 113 84 | #define POP_JUMP_IF_FALSE 114 85 | #define POP_JUMP_IF_TRUE 115 86 | #define LOAD_GLOBAL 116 87 | #define CONTINUE_LOOP 119 88 | #define SETUP_LOOP 120 89 | #define SETUP_EXCEPT 121 90 | #define SETUP_FINALLY 122 91 | #define LOAD_FAST 124 92 | #define STORE_FAST 125 93 | #define DELETE_FAST 126 94 | #define STORE_ANNOTATION 127 95 | #define RAISE_VARARGS 130 96 | #define CALL_FUNCTION 131 97 | #define MAKE_FUNCTION 132 98 | #define BUILD_SLICE 133 99 | #define LOAD_CLOSURE 135 100 | #define LOAD_DEREF 136 101 | #define STORE_DEREF 137 102 | #define DELETE_DEREF 138 103 | #define CALL_FUNCTION_KW 141 104 | #define CALL_FUNCTION_EX 142 105 | #define SETUP_WITH 143 106 | #define EXTENDED_ARG 144 107 | #define LIST_APPEND 145 108 | #define SET_ADD 146 109 | #define MAP_ADD 147 110 | #define LOAD_CLASSDEREF 148 111 | #define BUILD_LIST_UNPACK 149 112 | #define BUILD_MAP_UNPACK 150 113 | #define BUILD_MAP_UNPACK_WITH_CALL 151 114 | #define BUILD_TUPLE_UNPACK 152 115 | #define BUILD_SET_UNPACK 153 116 | #define SETUP_ASYNC_WITH 154 117 | #define FORMAT_VALUE 155 118 | #define BUILD_CONST_KEY_MAP 156 119 | #define BUILD_STRING 157 120 | #define BUILD_TUPLE_UNPACK_WITH_CALL 158 121 | #define EXCEPT_HANDLER 257 -------------------------------------------------------------------------------- /stack.py: -------------------------------------------------------------------------------- 1 | class stack: 2 | def __init__(self,*,size): 3 | self.size = size 4 | self.stack = [] 5 | 6 | def push(self, value): 7 | assert len(self.stack)+1 <= self.size 8 | # print(self.stack) 9 | self.stack.append(value) 10 | 11 | def top(self): 12 | assert len(self.stack) != 0 13 | return self.stack[-1] 14 | 15 | def second(self): 16 | assert len(self.stack)-1 != 0 17 | return self.stack[-2] 18 | 19 | def pop(self): 20 | # assert len(self.stack) != 0 21 | return self.stack.pop() 22 | 23 | def set_value(self, index, value): 24 | assert len(self.stack)+1 <= self.size 25 | self.stack[index] = value 26 | 27 | def set_top(self, value): 28 | assert len(self.stack) != 0 29 | self.stack[-1] = value 30 | 31 | def set_second(self, value): 32 | assert len(self.stack)-1 != 0 33 | self.stack[-2] = value 34 | 35 | def peek(self,n): 36 | return self.stack[-n] 37 | 38 | def __repr__(self): 39 | return str(self.stack) 40 | 41 | def __len__(self): 42 | return len(self.stack) -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | path = os.getcwd()+"/test_files/" 4 | test_files = os.listdir(path) 5 | test_files = [path + file_ for file_ in test_files] 6 | print("获取测试所用的文件成功") 7 | for file_name in test_files: 8 | with open(file_name) as file_: 9 | line = file_.readline() 10 | print(line.strip()) 11 | 12 | run_code = subprocess.run( 13 | ["python", 'csandbox.py', file_name], 14 | stdout=subprocess.PIPE, 15 | timeout=3 16 | ) 17 | 18 | python = subprocess.run(["python", file_name], 19 | stdout=subprocess.PIPE, 20 | timeout=3 21 | ) 22 | 23 | if run_code.stdout == python.stdout: 24 | print("成功完成: "+file_name+" 的测试\n") 25 | else: 26 | print(file_name+" 测试失败") 27 | break 28 | else: 29 | print("所有测试文件都测试完毕,没有问题") 30 | -------------------------------------------------------------------------------- /test_files/test0.py: -------------------------------------------------------------------------------- 1 | """基础数据结构的创建""" 2 | a = "测试1" 3 | b = "测试2" 4 | 5 | # 元组 6 | x = (a, 2, 3, b, 5, 6) 7 | print(x) 8 | 9 | # 字典 10 | x = {1: "测试1", 2: "测试2"} 11 | print(x) 12 | x = {a: "测试1", b: "测试2"} 13 | print(x) 14 | 15 | # 列表 16 | x = [1, 2, 3, a, 5, b, 34] 17 | print(x) 18 | 19 | # 切片 20 | x = [1, 2, 3, a, 5, b, 34] 21 | print(x[1]) 22 | print(x[3:5]) 23 | print(x[3:6:2]) 24 | x[1:2] = [a, b] 25 | print(x) 26 | -------------------------------------------------------------------------------- /test_files/test1.py: -------------------------------------------------------------------------------- 1 | """简单测试文件""" 2 | a = [1, 2, 3, 4, 5, 6, 7, 8] 3 | x = a[:2] 4 | y = a[1] 5 | print(a) 6 | print(x) 7 | print(y) 8 | -------------------------------------------------------------------------------- /test_files/test2.py: -------------------------------------------------------------------------------- 1 | """函数测试文件""" 2 | a = 100 3 | 4 | 5 | def x(): 6 | a = 111 7 | print(a) 8 | 9 | 10 | def y(): 11 | global a 12 | a = 222 13 | print(a) 14 | 15 | 16 | print(a) 17 | x() 18 | print(a) 19 | y() 20 | print(a) 21 | -------------------------------------------------------------------------------- /test_files/test3.py: -------------------------------------------------------------------------------- 1 | """运算符测试文件""" 2 | a = 100 3 | b = 124 4 | 5 | 6 | def operator(): 7 | c = a + b 8 | print(c) 9 | print("加法运算结束\n") 10 | 11 | c = a - b 12 | print(c) 13 | print("减法运算结束\n") 14 | 15 | c = a * b 16 | print(c) 17 | print("乘法运算结束\n") 18 | 19 | c = a / b 20 | print(c) 21 | print("真除除法运算结束\n") 22 | 23 | c = a // b 24 | print(c) 25 | print("除法运算结束") 26 | 27 | c = a ** b 28 | print(c) 29 | print("乘方运算结束") 30 | 31 | 32 | operator() 33 | 34 | a = 21 35 | b = 10 36 | c = 0 37 | 38 | c = a + b 39 | print("1 - c 的值为:", c) 40 | 41 | c = a - b 42 | print("2 - c 的值为:", c) 43 | 44 | c = a * b 45 | print("3 - c 的值为:", c) 46 | 47 | c = a / b 48 | print("4 - c 的值为:", c) 49 | 50 | c = a % b 51 | print("5 - c 的值为:", c) 52 | 53 | # 修改变量 a 、b 、c 54 | a = 2 55 | b = 3 56 | c = a**b 57 | print("6 - c 的值为:", c) 58 | 59 | a = 10 60 | b = 5 61 | c = a//b 62 | print("7 - c 的值为:", c) 63 | 64 | 65 | a = 21 66 | b = 10 67 | c = 0 68 | 69 | c = a + b 70 | print("1 - c 的值为:", c) 71 | 72 | c += a 73 | print("2 - c 的值为:", c) 74 | 75 | c *= a 76 | print("3 - c 的值为:", c) 77 | 78 | c /= a 79 | print("4 - c 的值为:", c) 80 | 81 | c = 2 82 | c %= a 83 | print("5 - c 的值为:", c) 84 | 85 | c **= a 86 | print("6 - c 的值为:", c) 87 | 88 | c //= a 89 | print("7 - c 的值为:", c) 90 | -------------------------------------------------------------------------------- /test_files/test4.py: -------------------------------------------------------------------------------- 1 | """getattr 测试""" 2 | 3 | a = 100 + 2389j 4 | print(a.real) 5 | print(a.imag) 6 | -------------------------------------------------------------------------------- /test_files/test5.py: -------------------------------------------------------------------------------- 1 | """用于测试比较运算符""" 2 | # 小于等于 le 3 | a = (100 <= 1000) 4 | print(a) 5 | a = (10000 <= 100) 6 | print(a) 7 | a = (100 <= 100) 8 | print(a) 9 | 10 | # 小于 lt 11 | a = (100 < 1000) 12 | print(a) 13 | a = (10000 < 100) 14 | print(a) 15 | a = (100 < 100) 16 | print(a) 17 | 18 | # 大于等于 ge 19 | a = (100 >= 1000) 20 | print(a) 21 | a = (10000 >= 100) 22 | print(a) 23 | a = (100 >= 100) 24 | print(a) 25 | 26 | # 大于 gt 27 | a = (100 > 1000) 28 | print(a) 29 | a = (10000 > 100) 30 | print(a) 31 | a = (100 > 100) 32 | print(a) 33 | 34 | # 等于 eq 35 | a = (100 == 1000) 36 | print(a) 37 | a = (10000 == 100) 38 | print(a) 39 | a = (100 == 100) 40 | print(a) 41 | 42 | # 不等于 ne 43 | a = (100 != 1000) 44 | print(a) 45 | a = (10000 != 100) 46 | print(a) 47 | a = (100 != 100) 48 | print(a) 49 | 50 | # in contains 51 | a = [1, 2, 3, 4] in [1, 2, 3, 4, 5] 52 | print(a) 53 | a = [1, 2, 3, 4, 5, 6] in [1, 2, 3, 4] 54 | 55 | # not in 56 | a = [1, 2, 3, 4] not in [1, 2, 3, 4, 5] 57 | print(a) 58 | a = [1, 2, 3, 4, 5, 6] not in [1, 2, 3, 4] 59 | 60 | # is 61 | a = None is None 62 | print(a) 63 | a = 1 is None 64 | print(a) 65 | 66 | # is_not 67 | a = None is not None 68 | print(a) 69 | a = 1 is not None 70 | print(a) 71 | 72 | # and 73 | x = True and True 74 | print(x) 75 | x = False and True 76 | print(x) 77 | 78 | # or 79 | x = True or False 80 | print(x) 81 | x = False or False 82 | print(x) 83 | 84 | 85 | a = 10 86 | b = 20 87 | 88 | if (a and b): 89 | print("1 - 变量 a 和 b 都为 true") 90 | else: 91 | print("1 - 变量 a 和 b 有一个不为 true") 92 | 93 | if (a or b): 94 | print("2 - 变量 a 和 b 都为 true,或其中一个变量为 true") 95 | else: 96 | print("2 - 变量 a 和 b 都不为 true") 97 | 98 | # 修改变量 a 的值 99 | a = 0 100 | if (a and b): 101 | print("3 - 变量 a 和 b 都为 true") 102 | else: 103 | print("3 - 变量 a 和 b 有一个不为 true") 104 | 105 | if (a or b): 106 | print("4 - 变量 a 和 b 都为 true,或其中一个变量为 true") 107 | else: 108 | print("4 - 变量 a 和 b 都不为 true") 109 | 110 | if not(a and b): 111 | print("5 - 变量 a 和 b 都为 false,或其中一个变量为 false") 112 | else: 113 | print("5 - 变量 a 和 b 都为 true") 114 | 115 | 116 | a = 10 117 | b = 20 118 | lists = [1, 2, 3, 4, 5] 119 | 120 | if (a in lists): 121 | print("1 - 变量 a 在给定的列表中 list 中") 122 | else: 123 | print("1 - 变量 a 不在给定的列表中 list 中") 124 | 125 | if (b not in lists): 126 | print("2 - 变量 b 不在给定的列表中 list 中") 127 | else: 128 | print("2 - 变量 b 在给定的列表中 list 中") 129 | 130 | # 修改变量 a 的值 131 | a = 2 132 | if (a in lists): 133 | print("3 - 变量 a 在给定的列表中 list 中") 134 | else: 135 | print("3 - 变量 a 不在给定的列表中 list 中") 136 | -------------------------------------------------------------------------------- /test_files/test6.py: -------------------------------------------------------------------------------- 1 | """if 的测试文件""" 2 | 3 | if 100 > 1000: 4 | print(True) 5 | else: 6 | print(False) 7 | 8 | if 100 < 1000: 9 | print(True) 10 | else: 11 | print(False) 12 | 13 | if 100 > 1000: 14 | print("测试1") 15 | elif 100 > 99: 16 | print("测试2") 17 | else: 18 | print("测试3") 19 | 20 | if 100 == 1000: 21 | print("测试1") 22 | elif 2000 == 100: 23 | print("测试2") 24 | else: 25 | print("测试3") 26 | 27 | if 100 < 1000: 28 | print("测试1") 29 | elif 2000 == 100: 30 | print("测试2") 31 | else: 32 | print("测试3") 33 | 34 | if not None: 35 | print("测试1") 36 | else: 37 | print("测试2") 38 | 39 | if None is not None: 40 | print("测试1") 41 | else: 42 | print("测试2") 43 | 44 | a = 100 45 | if a >= 0: 46 | print(a) 47 | else: 48 | print(-a) 49 | 50 | a = 21 51 | b = 10 52 | c = 0 53 | 54 | if a == b: 55 | print("1 - a 等于 b") 56 | else: 57 | print("1 - a 不等于 b") 58 | 59 | if (a != b): 60 | print("2 - a 不等于 b") 61 | else: 62 | print("2 - a 等于 b") 63 | 64 | if (a < b): 65 | print("3 - a 小于 b") 66 | else: 67 | print("3 - a 大于等于 b") 68 | 69 | if (a > b): 70 | print("4 - a 大于 b") 71 | else: 72 | print("4 - a 小于等于 b") 73 | 74 | # 修改变量 a 和 b 的值 75 | a = 5 76 | b = 20 77 | if (a <= b): 78 | print("5 - a 小于等于 b") 79 | else: 80 | print("5 - a 大于 b") 81 | 82 | if (b >= a): 83 | print("6 - b 大于等于 a") 84 | else: 85 | print("6 - b 小于 a") 86 | -------------------------------------------------------------------------------- /test_files/test7.py: -------------------------------------------------------------------------------- 1 | """for 的测试文件""" 2 | 3 | for x in [1, 2, 3, 4, 5, 6, 6, 7, 5]: 4 | print(x) 5 | 6 | for x in [1, 2, 3, 4, 5, 6, 6, 7, 5]: 7 | print(x) 8 | else: 9 | print("正常结束") 10 | 11 | 12 | for x in [1, 2, 3, 4, 5, 6, 7]: 13 | if x == 4: 14 | print("continue") 15 | continue 16 | if x == 5: 17 | break 18 | print(x) 19 | else: 20 | print("正常结束") 21 | 22 | 23 | def bubble_sort(nums): 24 | for i in range(len(nums) - 1): # 这个循环负责设置冒泡排序进行的次数 25 | for j in range(len(nums) - i - 1): # j为列表下标 26 | if nums[j] > nums[j + 1]: 27 | nums[j], nums[j + 1] = nums[j + 1], nums[j] 28 | return nums 29 | 30 | 31 | print(bubble_sort([45, 32, 8, 33, 12, 22, 19, 97])) 32 | -------------------------------------------------------------------------------- /test_files/test8.py: -------------------------------------------------------------------------------- 1 | """位运算测试文件""" 2 | 3 | a = 296 4 | b = 46 5 | b |= a << 8 6 | print(b) 7 | 8 | b &= a >> 8 9 | print(b) 10 | 11 | a = 60 # 60 = 0011 1100 12 | b = 13 # 13 = 0000 1101 13 | print('a=', a, ':', bin(a), 'b=', b, ':', bin(b)) 14 | c = 0 15 | 16 | c = a & b # 12 = 0000 1100 17 | print("result of AND is ", c, ':', bin(c)) 18 | 19 | c = a | b # 61 = 0011 1101 20 | print("result of OR is ", c, ':', bin(c)) 21 | 22 | c = a ^ b # 49 = 0011 0001 23 | print("result of EXOR is ", c, ':', bin(c)) 24 | 25 | c = ~a # -61 = 1100 0011 26 | print("result of COMPLEMENT is ", c, ':', bin(c)) 27 | 28 | c = a << 2 # 240 = 1111 0000 29 | print("result of LEFT SHIFT is ", c, ':', bin(c)) 30 | 31 | c = a >> 2 # 15 = 0000 1111 32 | print("result of RIGHT SHIFT is ", c, ':', bin(c)) 33 | -------------------------------------------------------------------------------- /test_files/test9.py: -------------------------------------------------------------------------------- 1 | """各种排序算法的综合测试""" 2 | 3 | 4 | def pail_sort(my_list): 5 | 6 | max_num = max(my_list) 7 | min_num = min(my_list) 8 | 9 | Y_list = list() 10 | 11 | for i in range(min_num, max_num+1): 12 | zhao_list = [i, 0] 13 | Y_list.append(zhao_list) 14 | for m in my_list: 15 | for Y in Y_list: 16 | if Y[0] == m: 17 | Y[1] += 1 18 | 19 | result = list() 20 | 21 | for n in Y_list: 22 | for t in range(0, n[1]): 23 | result.append(n[0]) 24 | 25 | return result 26 | 27 | 28 | def main(): 29 | 30 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20] 31 | print("简单桶排序之前的序列:", Y_list) 32 | print("简单桶排序之后的序列:", pail_sort(Y_list)) 33 | 34 | 35 | if __name__ == '__main__': 36 | main() 37 | 38 | 39 | def bubble_sort(my_list): 40 | 41 | N = len(my_list) 42 | # 循环的次数 43 | circle_num = N-1 44 | 45 | while circle_num > 0: 46 | # 初始的游标值 47 | index_value = 0 48 | 49 | while index_value < circle_num: 50 | if my_list[index_value] < my_list[index_value+1]: 51 | pass 52 | else: 53 | my_list[index_value], my_list[index_value +1] = my_list[index_value + 1], my_list[index_value] 54 | 55 | # 游标右移一个单位 56 | index_value += 1 57 | 58 | circle_num -= 1 59 | 60 | print("冒泡排序之后的序列:", my_list) 61 | return my_list 62 | 63 | 64 | def main(): 65 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20] 66 | print("冒泡排序之前的序列:", Y_list) 67 | bubble_sort(Y_list) 68 | 69 | 70 | if __name__ == '__main__': 71 | main() 72 | 73 | 74 | def selection_sort(my_list): 75 | 76 | # N为列表元素的个数 77 | N = len(my_list) 78 | 79 | circle_num = 0 80 | 81 | # 需要进行N-1次循环 82 | while circle_num < N: 83 | 84 | # 每次循环开始的游标索引值 为 circle_num , 结束的索引值为N-1 85 | for m in range(circle_num, N): 86 | if my_list[circle_num] <= my_list[m]: 87 | pass 88 | else: 89 | my_list[circle_num], my_list[m] = my_list[m], my_list[circle_num] 90 | 91 | circle_num += 1 92 | 93 | print("选择排序之后的序列:", my_list) 94 | 95 | 96 | def main(): 97 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20] 98 | print("选择排序之前的序列:", Y_list) 99 | selection_sort(Y_list) 100 | pass 101 | 102 | 103 | if __name__ == '__main__': 104 | main() 105 | 106 | 107 | def insert_sort(my_list): 108 | N = len(my_list) 109 | finish_list = list() 110 | f_len = len(finish_list) 111 | finish_list.append(my_list[0]) 112 | # circle_num为待插入的值的索引 113 | for circle_num in range(1, N): 114 | for pre in range(0, circle_num): 115 | 116 | # 如果新加入的值比已排序的值小,就把新值加入到 已排序值的前面 117 | if my_list[circle_num] < finish_list[pre]: 118 | finish_list.insert(pre, my_list[circle_num]) 119 | break 120 | 121 | # 如果新加入的值比已排序的序列最大的值都大,那么 122 | elif my_list[circle_num] >= finish_list[-1]: 123 | finish_list.append(my_list[circle_num]) 124 | 125 | break 126 | # 如果新加入的值 比已排序的某个值大但比 已排序后面的值小 127 | elif my_list[circle_num] >= finish_list[pre] and my_list[circle_num] < finish_list[pre+1]: 128 | finish_list.insert(pre+1, my_list[circle_num]) 129 | break 130 | else: 131 | pass 132 | 133 | return finish_list 134 | 135 | 136 | def main(): 137 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20] 138 | print("插入排序之前的序列:", Y_list) 139 | insert_sort(Y_list) 140 | print("插入排序之后的序列:", insert_sort(Y_list)) 141 | 142 | 143 | if __name__ == '__main__': 144 | main() 145 | 146 | 147 | def q_sort(my_list, left, right): 148 | 149 | # 设置左右指针 150 | left_point = left 151 | right_point = right 152 | stand_num = left 153 | if left > right: 154 | return 155 | 156 | while left_point != right_point: 157 | 158 | # 先移动右指针,如果遇到 比基准值更小 的值,就停下来 159 | 160 | while (my_list[right_point] >= my_list[stand_num]) and (left_point < right_point): 161 | right_point -= 1 162 | 163 | # 再移动左指针,如果遇到比基准值更大的值,就停下来 164 | 165 | while (my_list[left_point] < my_list[stand_num]) and (left_point < right_point): 166 | left_point += 1 167 | 168 | # 找到了双方可交换的点后, 开始交换 169 | 170 | my_list[left_point], my_list[right_point] = my_list[right_point], my_list[left_point] 171 | 172 | # 将基准点 与 指针相遇的点互换 173 | 174 | if left_point == right_point: 175 | my_list[stand_num], my_list[left_point] = my_list[left_point], my_list[stand_num] 176 | 177 | q_sort(my_list, left, left_point-1) 178 | q_sort(my_list, right_point+1, right) 179 | 180 | return (my_list) 181 | 182 | 183 | def quick_sort(out_of_order): 184 | end = len(out_of_order) - 1 185 | start = 0 186 | q_sort(out_of_order, start, end) 187 | # print("排列完成的数组:",out_of_order) 188 | 189 | return out_of_order 190 | 191 | 192 | def main(): 193 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20] 194 | print("快速排序之前的序列:", Y_list) 195 | print("快速排序之后的序列:", quick_sort(Y_list)) 196 | 197 | 198 | if __name__ == '__main__': 199 | main() 200 | 201 | 202 | # 负责 将列表拆分 203 | def merge_sort(Y_list): 204 | 205 | if len(Y_list) <= 1: 206 | return Y_list 207 | 208 | # 先将未排序的列表进行分组 209 | num = len(Y_list) // 2 210 | 211 | left_list = merge_sort(Y_list[:num]) 212 | right_list = merge_sort(Y_list[num:]) 213 | 214 | # 将分组的列表交给merge函数, merge负责将列表合并 215 | return merge(left_list, right_list) 216 | 217 | 218 | # 负责将列表合并 219 | def merge(left, right): 220 | 221 | left_point = 0 222 | right_point = 0 223 | 224 | finish_list = list() 225 | 226 | while right_point < len(right) and left_point < len(left): 227 | 228 | if left[left_point] <= right[right_point]: 229 | finish_list.append(left[left_point]) 230 | left_point += 1 231 | 232 | else: 233 | finish_list.append(right[right_point]) 234 | right_point += 1 235 | 236 | finish_list += left[left_point:] 237 | finish_list += right[right_point:] 238 | 239 | return finish_list 240 | 241 | 242 | def main(): 243 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20] 244 | print("归并排序之前的序列:", Y_list) 245 | print("归并排序之后的序列:", merge_sort(Y_list)) 246 | 247 | 248 | if __name__ == '__main__': 249 | main() 250 | 251 | 252 | def shell_sort(Y_list): 253 | 254 | gap = len(Y_list) 255 | 256 | while gap >= 0: 257 | 258 | tem_list = list() 259 | 260 | if gap == 0: 261 | return Y_list 262 | 263 | # 将要抽取的值和索引保存到一个 列表里 264 | 265 | for index, value in enumerate(Y_list): 266 | if index % gap == 0: 267 | zhao_list = [index, value] 268 | tem_list.append(zhao_list) 269 | 270 | tem_value_list = list() 271 | 272 | for i in tem_list: 273 | tem_value_list.append(i[1]) 274 | tem_value_list = insert_sort(tem_value_list) 275 | 276 | for i, vv in enumerate(tem_value_list): 277 | 278 | tem_list[i][1] = vv 279 | 280 | # 排序好的值 替换 原位置的值 281 | for iv in tem_list: 282 | 283 | Y_list[iv[0]] = iv[1] 284 | 285 | gap = gap // 2 286 | 287 | return Y_list 288 | 289 | 290 | def insert_sort(my_list): 291 | N = len(my_list) 292 | finish_list = list() 293 | f_len = len(finish_list) 294 | finish_list.append(my_list[0]) 295 | # circle_num为待插入的值的索引 296 | for circle_num in range(1, N): 297 | for pre in range(0, circle_num): 298 | 299 | # 如果新加入的值比已排序的值小,就把新值加入到 已排序值的前面 300 | if my_list[circle_num] < finish_list[pre]: 301 | finish_list.insert(pre, my_list[circle_num]) 302 | break 303 | 304 | # 如果新加入的值比已排序的序列最大的值都大,那么 305 | elif my_list[circle_num] >= finish_list[-1]: 306 | finish_list.append(my_list[circle_num]) 307 | 308 | break 309 | # 如果新加入的值 比已排序的某个值大但比 已排序后面的值小 310 | elif my_list[circle_num] >= finish_list[pre] and my_list[circle_num] < finish_list[pre+1]: 311 | finish_list.insert(pre+1, my_list[circle_num]) 312 | break 313 | else: 314 | pass 315 | 316 | return finish_list 317 | 318 | 319 | def main(): 320 | 321 | Y_list = [100, 54, 26, 63, 12, 22, 93, 17, 12, 77, 31, 44, 55, 20] 322 | print("希尔排序之前的序列:", Y_list) 323 | print("希尔排序之后的序列:", shell_sort(Y_list)) 324 | 325 | 326 | if __name__ == '__main__': 327 | main() 328 | 329 | 330 | # 实现快排 331 | def quicksort(nums): 332 | if len(nums) <= 1: 333 | return nums 334 | 335 | # 左子数组 336 | less = [] 337 | # 右子数组 338 | greater = [] 339 | # 基准数 340 | base = nums.pop() 341 | 342 | # 对原数组进行划分 343 | for x in nums: 344 | if x < base: 345 | less.append(x) 346 | else: 347 | greater.append(x) 348 | 349 | # 递归调用 350 | return quicksort(less) + [base] + quicksort(greater) 351 | 352 | 353 | def main(): 354 | nums = [6, 1, 2, 7, 9, 3, 4, 5, 10, 8] 355 | print(quicksort(nums)) 356 | 357 | def x(y): return y 358 | 359 | 360 | if __name__ == '__main__': 361 | main() 362 | --------------------------------------------------------------------------------