汉王电纸书官网的问题?

2013Python程序设计期末试卷A_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
2013Python程序设计期末试卷A
上传于||暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩7页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢Python源码分析2&-&一个简单的Python程序的执行
本文主要通过跟踪一个非常简单的Python程序的执行,简单讨论Python实现的基本框架和结构。
要执行Python程序如下,功能非常简单:从1加到10再打印出来
for i in range(1,
如果想要在Windows下面用VS 2005调试Python,可以通过下面步骤设置:
把Startup Project设置成Python,这样就可以直接通过F5来启动Python
右键单击Python这个Project,选择Properties。在对话框中的Configuration
Properties-&Debugging下面,把Command Arguments设置为-d
test.py。其中test.py就是我们所要调试程序的名字。-d表示打开调试开关,可以看到额外的调试信息。
好了,设置完毕之后可以直接按下F10来单步追踪该程序的执行了。
首先,F10,启动程序,可以看到Python的main函数中没有什么内容,只是简单的调用Py_Main。Py_Main顾名思义自然是主函数了,分几大部分:
分析命令行和环境变量
调用Py_Initialize初始化
根据命令行的内容执行进入不同的执行模式
(command) {
&&&&&&&&sts
= PyRun_SimpleStringFlags(command, &cf) != 0;
&&&&&&&&free(command);
else if (module) {
&&&&&&&&sts
= RunModule(module);
&&&&&&&&free(module);
&&&&&&&&if
(filename == NULL && stdin_is_interactive) {
&&&&&&&&&&&&RunStartupFile(&cf);
&&&&&&&&sts
= PyRun_AnyFileExFlags(
&&&&&&&&&&&&fp,
&&&&&&&&&&&&filename
== NULL ? "" : filename,
&&&&&&&&&&&&filename
!= NULL, &cf) != 0;
从上面的代码可以很容易看出,一共有3种执行方式:
Command模式,执行单条Python语句。通过-c指定。语句内容存放在command变量中。调用PyRun_SimpleStringFlags来执行。
Module模式,执行整个Module。通过-m指定。调用RunModule来执行。
File模式,执行Python源程序和交互都归在此类。可以看到,如果未指定文件名并且stdin是交互的话,会执行一个PYTHONSTARTUP所指定的源程序。
4. 最后调用Py_Finalize结束
这里我们关注的主要对象自然是PyRun_AnyFileExFlags,其内容如下:
PyRun_AnyFileExFlags(FILE *fp, const
char *filename, int closeit,
PyCompilerFlags *flags)
(filename == NULL)
&&&&&&&&filename
(Py_FdIsInteractive(fp, filename)) {
&&&&&&&&int
err = PyRun_InteractiveLoopFlags(fp, filename, flags);
&&&&&&&&if
&&&&&&&&&&&&fclose(fp);
&&&&&&&&return
&&&&&&&&return
PyRun_SimpleFileExFlags(fp, filename, closeit, flags);
首先判断文件是否是交互的,如果是,则调用PyRun_InteractiveLoopFlags(fp, filename,
flags),否则调用PyRun_SimpleFlagExFlags。PyRun_InteractiveLoopFlags和PyRun_SimpleFileExFlags基本上区别不大,本质上作的事情都是一样,只不过一个是以语句为单位执行,一个是以程序为单位来执行。所以这里还是以分析PyRun_SimpleFileExFlags为主。
PyRun_SimpleFileExFlags(FILE *fp,
const char *filename, int closeit,
&&&&&&&&&&&&PyCompilerFlags
&&&&PyObject
*m, *d, *v;
= PyImport_AddModule("__main__");
(m == NULL)
&&&&&&&&return
= PyModule_GetDict(m);
(PyDict_GetItemString(d, "__file__") == NULL) {
&&&&&&&&PyObject
*f = PyString_FromString(filename);
&&&&&&&&if
(f == NULL)
&&&&&&&&&&&&return
&&&&&&&&if
(PyDict_SetItemString(d, "__file__", f) & 0) {
&&&&&&&&&&&&Py_DECREF(f);
&&&&&&&&&&&&return
&&&&&&&&Py_DECREF(f);
= filename + strlen(filename) - 4;
(maybe_pyc_file(fp, filename, ext, closeit)) {
&&&&&&&&if
&&&&&&&&&&&&fclose(fp);
&&&&&&&&if
((fp = fopen(filename, "rb")) == NULL) {
&&&&&&&&&&&&fprintf(stderr,
"python: Can't reopen .pyc file/n");
&&&&&&&&&&&&return
&&&&&&&&if
(strcmp(ext, ".pyo") == 0)
&&&&&&&&&&&&Py_OptimizeFlag
= run_pyc_file(fp, filename, d, d, flags);
= PyRun_FileExFlags(fp, filename, Py_file_input, d, d,
&&&&&&&&&&&&&&&&
closeit, flags);
(v == NULL) {
&&&&&&&&PyErr_Print();
&&&&&&&&return
&&&&Py_DECREF(v);
(Py_FlushLine())
&&&&&&&&PyErr_Clear();
&&&&return
可以看到此函数主要的作的事情是:
创建Module __main__,任何Python脚本都会自动属于__main__
设置__file__为当前文件名字
检查是否为.pyc /
.pyo文件。Maybe_pyc_file会根据文件的扩展名和文件内容的头两个字节是否为0xf2b3来判断是否是pyc/pyo文件。如果是pyc或者pyo,调用run_pyc_file来直接执行Python的Bytecode。
否则,调用PyRun_FileExFlags来执行Python的源程序
Run_pyc_file不是本文分析的重点,我们还是先来看一下PyRun_FileExFlags这个函数:
PyObject *
PyRun_FileExFlags(FILE
*fp, const char *filename, int start, PyObject *globals,
PyObject *locals, int closeit, PyCompilerFlags *flags)
&&&&PyObject
&&&&mod_ty
&&&&PyArena
*arena = PyArena_New();
(arena == NULL)
&&&&&&&&return
= PyParser_ASTFromFile(fp, filename, start, 0, 0,
&&&&&&&&&&&&&&&&
flags, NULL, arena);
(mod == NULL) {
&&&&&&&&PyArena_Free(arena);
&&&&&&&&return
&&&&&&&&fclose(fp);
= run_mod(mod, filename, globals, locals, flags, arena);
&&&&PyArena_Free(arena);
&&&&return
这个函数非常简单,但是却涵盖了整个Python源程序的运行的过程:
创建一个Arena对象。此对象是用于内存分配用的,维护分配的原始内存和PyObject对象。
调用PyParser_ASTFromFile。 此函数会通过词法分析和语法分析得到源程序所对应的AST(Abstract
Syntax Tree)。
调用Run_mod
PyParser_ASTFromFile的代码如下:
PyParser_ASTFromFile(FILE *fp, const
char *filename, int start, char *ps1,
char *ps2, PyCompilerFlags *flags, int *errcode,
PyArena *arena)
&&&&mod_ty
&&&&perrdetail
*n = PyParser_ParseFileFlags(fp, filename,
&_PyParser_Grammar,
&&&&&&&&&&&&&&&&start,
ps1, ps2, &err, PARSER_FLAGS(flags));
&&&&&&&&mod
= PyAST_FromNode(n, flags, filename, arena);
&&&&&&&&PyNode_Free(n);
&&&&&&&&return
&&&&&&&&err_input(&err);
&&&&&&&&if
&&&&&&&&&&&&*errcode
&&&&&&&&return
首先,PyParser_ParseFileFlags分析文件,生成CST(Concrete Syntax
Tree)并将其根结点放到node*之中。Node的结构如下:
typedef struct _node
short&&&&&&&&&&&&n_
char&&&&&&&&&&&&*n_
int&&&&&&&&&&&&n_
int&&&&&&&&&&&&n_col_
int&&&&&&&&&&&&n_
_node&&&&*n_
n_type代表着语法树的结点的类型,对应着Python-2.5/Grammar/Grammar文件中的文法中的终结符/非终结符,主要在graminit.h和token.h中定义。在后面的文章中会详述。N_str则是对应的字符串的内容。N_lineno
n_col_offset分别代表对应行号和列号。最后的两个n_nchildren和n_child表示此节点共有n_nchildren个子结点。
下面的函数可以用来访问node。大部分的函数都无需解释,除了RCHILD,RCHILD表示从右往左第几个,i给负值。比如RCHILD(n,
-1)就是从右往左第一个结点。
NCH(n)&&&&&&&&((n)-&n_nchildren)
#define CHILD(n,
i)&&&&(&(n)-&n_child[i])
#define RCHILD(n,
i)&&&&(CHILD(n,
NCH(n) + i))
TYPE(n)&&&&&&&&((n)-&n_type)
STR(n)&&&&&&&&((n)-&n_str)
文中的Python程序的CST看起来大致是这样的:
&<img STYLE="BorDer-Top: BorDer-riGHT: BorDer-BoTToM: BorDer-LeFT: medium none" ALT="" src="/blog7style/images/common/sg_trans.gif" real_src ="http://p.blog.csdn.net/images/p_blog_csdn_net/ATField/Python%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%902-1.jpg"
TITLE="Python源码分析2&-&一个简单的Python程序的执行" />
图中省略了很多细节,因为是CST的关系,分析过程中有大量冗余信息,主要是每一步通过DFA分析的结点都列在这棵树里面了。由于篇幅的关系就不把整棵树画出来了。
那么CST是怎么生成的呢?在PyParser_ParseFileFlags中:
PyParser_ParseFileFlags(FILE *fp,
const char *filename, grammar *g, int start,
&&&&&&&&&&&&char
*ps1, char *ps2, perrdetail *err_ret, int flags)
&&&&struct
tok_state *
&&&&initerr(err_ret,
filename);
((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
&&&&&&&&err_ret-&error
= E_NOMEM;
&&&&&&&&return
&&&&tok-&filename
(Py_TabcheckFlag || Py_VerboseFlag) {
&&&&&&&&tok-&altwarning
= (filename != NULL);
&&&&&&&&if
(Py_TabcheckFlag &= 2)
&&&&&&&&&&&&tok-&alterror++;
&&&&return
parsetok(tok, g, start, err_ret, flags);
PyParser_ParserFileFlags首先创建tok_state,也就是词法分析器的对象,之后调用parsetok。Parsetok的代码量稍多,这里就不全部列出来了。主干代码如下:
static node
parsetok(struct
tok_state *tok, grammar *g, int start, perrdetail
int flags)
&&&&parser_state
started = 0, handling_import = 0, handling_with = 0;
= PyParser_New(g, start);
&&&&&&&&type
= PyTokenizer_Get(tok, &a, &b);
&&&&&&&&if
((err_ret-&error = PyParser_AddToken(ps, (int)type, str,
tok-&lineno, col_offset, &(err_ret-&expected))) != E_OK)
&&&&&&&&&&&&if
(err_ret-&error != E_DONE) {
&&&&&&&&&&&&&&&&PyObject_FREE(str);
&&&&&&&&&&&&&&&&err_ret-&token
&&&&&&&&&&&&}&&&&&&&&&&&&&&&&
&&&&&&&&&&&&
(err_ret-&error == E_DONE) {
&&&&&&&&ps-&p_tree
&&&&PyParser_Delete(ps);
(n == NULL) {
&&&&&&&&//
error processing
else if (tok-&encoding != NULL) {
&&&&&&&&node*
r = PyNode_New(encoding_decl);
&&&&&&&&if
&&&&&&&&&&&&err_ret-&error
= E_NOMEM;
&&&&&&&&&&&&n
&&&&&&&&&&&&goto
&&&&&&&&r-&n_str
&&&&&&&&r-&n_nchildren
&&&&&&&&r-&n_child
&&&&&&&&tok-&encoding
&&&&PyTokenizer_Free(tok);
&&&&return
里面最重要的是两个函数调用:
PyTokenizer_Get,是用来进行词法分析的,把源程序分解为Token的序列(比如变量名,运算符,关键字等都属于Token)
PyParser_AddToken,把Token加入到DFA状态机中进行语法分析,根据当前的状态和输入的Token,根据跳转表跳转到不同的状态,并依照这个过程生成CST
由于篇幅有限,这个两个函数的实现细节会在以后的文章详细分析。
在PyParser_ParserFileFlags得到了语法树之后,PyAST_FromNode会将CST转换为AST,存入mod_ty中。
typedef _mod
struct _mod
enum _mod_kind
_mod是AST的根结点,代表整个Module。在Python-ast.h中定义着所有AST结点的结构,mod_ty和expr_ty也在其中,后者显然代表着一个表达式。
adsl_seq代表一个变长的指针数组,结构定义如下:
typedef struct
*elements[1];
这个结构稍微有些特殊的是elements在struct中只有一个元素。其实这个struct可以支持任意多个元素,正因为如此,普通的定义方法是不行的。因此这里只定义一个元素,然后在分配计算实际的大小(会比adsl_seq这个结构要大),然后访问元素的时候直接用elements,因为C/C++是不会检查越界的。这种做法在C/C++系统编程中还是比较常见的。
Adsl_seq粗看上去只保存了void
*,也就是说具体类型信息丢失了,那么当要遍历整个树的时候是如何做的呢?其实当遍历到某个结点(比如Module/Expression)的时候,便可以确定该结点所支持的子结点是什么类型,然后直接转强制转换就可以了。还有一种情况是在结点中直接记录的是具体的有类型的AST结点,比如expr_ty,就更加容易了。
文中Python代码对应的AST大致如下:
&<img STYLE="BorDer-Top: BorDer-riGHT: BorDer-BoTToM: BorDer-LeFT: medium none" ALT="" src="/blog7style/images/common/sg_trans.gif" real_src ="http://p.blog.csdn.net/images/p_blog_csdn_net/ATField/Python%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%902-2.jpg"
TITLE="Python源码分析2&-&一个简单的Python程序的执行" />
同样的,也省略了一些细节。可以看到,最终的结果要比CST要少很多,比较接近源代码本来的样子。
当PyParser_ASTFromFile执行完毕之后,回到PyRun_FileExFlags,执行下一步,调用run_mod,也就是执行这颗AST所代表的程序。
static PyObject
run_mod(mod_ty mod,
const char *filename, PyObject *globals, PyObject
PyCompilerFlags *flags, PyArena *arena)
&&&&PyCodeObject
&&&&PyObject
= PyAST_Compile(mod, filename, flags, arena);
(co == NULL)
&&&&&&&&return
= PyEval_EvalCode(co, globals, locals);
&&&&Py_DECREF(co);
&&&&return
Run_mod非常直接,分两步走:
编译AST,生成PyCodeObject对象,也就是ByteCode。
调用PyEval_EvalCode执行PyCodeObject,也就是通过VM直接执行bytecode。如果是执行.pyc/.pyo代码的话,直接从文件中读出信息创建好PyCodeObject对象就可以直接执行了,也是调用这个函数。
执行完PyEval_EvalCode之后可以看到55被打印出来了。
总结一下,Python执行程序的过程总共有以下几步:
Tokenizer进行词法分析,把源程序分解为Token
Parser根据Token创建CST
CST被转换为AST
AST被编译为字节码
执行字节码
后面的文章中我会对1~5这5步分别进行详细分析,今天就先写到这里。&
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。中国领先的IT技术网站
51CTO旗下网站
Python程序的执行原理
Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后虚拟机一条一条执行字节码指令,从而完成程序的执行。
作者:佚名来源:tech.uc| 10:35
1. 过程概述
Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后虚拟机一条一条执行字节码指令,从而完成程序的执行。
字节码在Python虚拟机程序里对应的是PyCodeObject对象。
.pyc文件是字节码在磁盘上的表现形式。
3. pyc文件
PyCodeObject对象的创建时机是模块加载的时候,即import。
Python test.py会对test.py进行编译成字节码并解释执行,但是不会生成test.pyc。
如果test.py加载了其他模块,如import util,Python会对util.py进行编译成字节码,生成util.pyc,然后对字节码解释执行。
如果想生成test.pyc,我们可以使用Python内置模块py_compile来编译。
加载模块时,如果同时存在.py和.pyc,Python会尝试使用.pyc,如果.pyc的编译时间早于.py的修改时间,则重新编译.py并更新.pyc。
4. PyCodeObject
Python代码的编译结果就是PyCodeObject对象。
typedef&struct&{&&&&&PyObject_HEAD&&&&&int&co_&&&&&&&&/*&位置参数个数&*/&&&&&int&co_&&&&&&&&&/*&局部变量个数&*/&&&&&int&co_&&&&&&&/*&栈大小&*/&&&&&int&co_&&&&&&&&PyObject&*co_&&&&&&/*&字节码指令序列&*/&&&&&PyObject&*co_&&&&/*&所有常量集合&*/&&&&&PyObject&*co_&&&&&/*&所有符号名称集合&*/&&&&&PyObject&*co_&&/*&局部变量名称集合&*/&&&&&PyObject&*co_&&/*&闭包用的的变量名集合&*/&&&&&PyObject&*co_&&/*&内部嵌套函数引用的变量名集合&*/&&&&&/*&The&rest&doesn&t&count&for&hash/cmp&*/&&&&&PyObject&*co_&&/*&代码所在文件名&*/&&&&&PyObject&*co_&&&&&&/*&模块名|函数名|类名&*/&&&&&int&co_&&&&&/*&代码块在文件中的起始行号&*/&&&&&PyObject&*co_&&&&/*&字节码指令和行号的对应关系&*/&&&&&void&*co_&&&/*&for&optimization&only&(see&frameobject.c)&*/&}&PyCodeO&
5. pyc文件格式
加载模块时,模块对应的PyCodeObject对象被写入.pyc文件,格式如下:
6. 分析字节码
6.1 解析PyCodeObject
Python提供了内置函数compile可以编译Python代码和查看PyCodeObject对象,如下:
Python代码[test.py]
s&=&&hello&&&def&func():&&&&&print&s&&func()&
在Python交互式shell里编译代码得到PyCodeObject对象:
dir(co)已经列出co的各个域,想查看某个域直接在终端输出即可:
test.py的PyCodeObject
co.co_argcount&&&&0&co.co_nlocals&&&&&0&co.co_names&&&&&&&(&s&,&&func&)&co.co_varnames&&&&(&s&,&&func&)&co.co_consts&&&&&&(&hello&,&&code&object&func&at&0x2aaeeec57110,&file&&test.py&,&line&3&,&None)&co.co_code&&&&&&&&&d\x00\x00Z\x00\x00d\x01\x00\x84\x00\x00Z\x01\x00e\x01\x00\x83\x00\x00\x01d\x02\x00S&&
Python解释器会为函数也生成的字节码PyCodeObject对象,见上面的co_consts[1]
func的PyCodeObject
func.co_argcount&&&0&func.co_nlocals&&&&0&func.co_names&&&&&&(&s&,)&func.co_varnames&&&()&func.co_consts&&&&&(None,)&func.co_code&&&&&&&&t\x00\x00GHd\x00\x00S&&
co_code是指令序列,是一串二进制流,它的格式和解析方法见6.2。
6.2 解析指令序列
指令序列co_code的格式
test.py的指令序列
func函数的指令序列
第一列表示以下几个指令在py文件中的行号;
第二列是该指令在指令序列co_code里的偏移量;
第三列是指令opcode的名称,分为有操作数和无操作数两种,opcode在指令序列中是一个字节的整数;
第四列是操作数oparg,在指令序列中占两个字节,基本都是co_consts或者co_names的下标;
第五列带括号的是操作数说明。
7. 执行字节码
Python虚拟机的原理就是模拟可执行程序再X86机器上的运行,X86的运行时栈帧如下图:
假如test.py用C语言来实现,会是下面这个样子:
const&char&*s&=&&hello&;&&void&func()&{&&&&&printf(&%s\n&,&s);&}&&int&main()&{&&&&&func();&&&&&return&0;&}&
Python虚拟机的原理就是模拟上述行为。当发生函数调用时,创建新的栈帧,对应Python的实现就是PyFrameObject对象。
7.1 PyFrameObject
typedef&struct&_frame&{&&&&&PyObject_VAR_HEAD&&&&&struct&_frame&*f_&&&&/*&调用者的帧&*/&&&&&PyCodeObject&*f_&&&&&/*&帧对应的字节码对象&*/&&&&&PyObject&*f_&&&&&/*&内置名字空间&*/&&&&&PyObject&*f_&&&&&&/*&全局名字空间&*/&&&&&PyObject&*f_&&&&&&&/*&本地名字空间&*/&&&&&PyObject&**f_&&/*&运行时栈底&*/&&&&&PyObject&**f_&&&&/*&运行时栈顶&*/&&&&&&&.&}&
那么对应Python的运行时栈就是这样子:
7.2 执行指令
执行test.py的字节码时,会先创建一个栈帧,以下用f表示当前栈帧,执行过程注释如下:
test.py的符号名集合和常量集合
co.co_names&&&(&s&,&&func&)&co.co_consts&&(&hello&,&&object&func&at&0x2aaeeec57110,&file&&test.py&,&line&3,&None)&
test.py的指令序列
上面的CALL_FUNCTION指令执行时,会创建新的栈帧,并执行func的字节码指令,以下用f表示当前栈帧,func的字节码执行过程如下:
func函数的符号名集合和常量集合
func.co_names&&&&&&&(&s&,)&func.co_consts&&&&&&(None,)&
func函数的指令序列
7.3 查看栈帧
如果你想查看当前栈帧,Python提供了sys._getframe()方法可以获取当前栈帧,你只需要在代码里加入代码如下:
def&func():&&&&&import&sys&&&&&frame&=&sys._getframe()&&&&&print&frame.f_locals&&&&&print&frame.f_globals&&&&&print&frame.f_back.f_locals&&&&&#你可以打印frame的各个域&&&&&print&s&&&
原文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
热点热点访谈关注头条
24H热文一周话题本月最赞
讲师:1人学习过
讲师:35人学习过
讲师:0人学习过
精选博文论坛热帖下载排行
本书共22章,包括操作符、控制执行流程、访问权限控制、复用类、多态、接口、通过异常处理错误、字符串、泛型、数组、容器深入研究、Java I...
订阅51CTO邮刊> python-异常处理有一种说法:程序错误可分为,编译时错误和运行时错误。写过c程序的人都知道,c
python-异常处理有一种说法:程序错误可分为,编译时错误和运行时错误。写过c程序的人都知道,c
发布时间: & &
浏览:56 & &
回复:0 & &
悬赏:0.0希赛币
python-异常处理
有一种说法:程序错误可分为,编译时错误和运行时错误。写过c程序的人都知道,c程序是最容易出现一些莫名其妙的运行时错误,其实也不算莫名其妙,只是编程时不小心出错,但是编译时候却毫无问题,运行时却总得不到自己想要的结果。编译时错误,其实很常见,语法错误之类的都算,在程序编译时候就提示的错误。而运行时错误是程序在加载运行时出现的错误,比如数组下标越界,除数为0等,在编译时候无法判断的错误。java 、python等语言,使用try。。(catch/except)块来捕获这一类错误,也就是我们常说的异常。其实学过java的人应该比较熟悉Error和Exception这两大类别的错误。。。然后再有不懂的。。赶紧自己先去科普一下。。python 属于面向对象语言,程序抛出的异常,其实也是一个类。常见的异常类如下:异常 描述NameError 尝试访问一个没有申明的变量ZeroDivisionError 除数为0SyntaxError 语法错误IndexError 索引超出序列范围KeyError 请求一个不存在的字典关键字IOError 输入输出错误(比如你要读的文件不存在)AttributeError 尝试访问未知的对象属性ValueError 传给函数的参数类型不正确,比如给int()函数传入字符串形 python的try语句有两种风格:一种是处理异常(try/except/else)try/except/else风格try:&&& &语句& #运行别的代码except &名字&:&&& &语句& #如果在try部份引发了'name'异常except &名字&,&数据&:&&& &语句& #如果引发了'name'异常,获得附加的数据else:&&& &语句& #如果没有异常发生 eg:a = 0b = 4c = 2try:&& f = b / a #f = b / cexcept ZeroDivisionError, e:&& print eelse:&& print f----------------------------------------------------------------------------------------------- 二种是无论是否发生异常都将执行最后的代码(try/finally) try/finally风格try:&&& &语句&finally:&&& &语句& #退出try时总会执行a = 0b = 4r = 10try:&& r = b / aexcept ZeroDivisionError, e:&& print efinally:&& print r--------------------------------------------------------------------------------------抛出异常:(有时候程序需要主动抛出异常,然后这种情况我们怎么实现呢?)格式如下:&&&
raise [SomeException [, args [,traceback]]&
第一个参数,SomeException必须是一个异常类,或异常类的实例 第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。第三个参数traceback很少用,主要是用来提供一个跟中记录对象(traceback)eg:try:&&&& raise NameError,('Throw Exception')except NameError, e:&&&& print e& #结果返回:Throw Exception
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&Python 程序在cmd执行的import问题解决 -
- ITeye技术网站
博客分类:
建成工程的python程序,经常启动函数在某一个模块下,一旦其中有引用本模块以外的情况,就会报错说某某模块找不到:
有两种方式可以解决环境变量的问题:
一种是cmd命令执行前加上:
SET PYTHONPATH=.
python main\main.py
F:/Workspaces/PythonWorkspace/AudioTesting/testAudio/
另一种是在python程序内加上环境变量的根目录:
# === import project path ===
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
# ===========================
本人比较倾向于第一种,因为不用去关心路径的名字、层级,只要在根目录下执行这个命令即可
浏览: 98207 次
来自: 北京
发内网邮件发不了,求指导}

我要回帖

更多关于 汉王电纸书和kindle 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信