Ⅰ python怎样使用解释器
大学里计算机科学最吸引我的地方就是编译器。最神奇的是,编译器是如何读出我写的那些烂代码,并且还能生成那么复杂的程序。当我终于选了一门编译方面的课程时,我发现这个过程比我想的要简单得多。
在本系列的文章中,我会试着通过为一种基本命令语言IMP写一个解释器,来展示这种简易性。因为IMP是一个简单广为人知的语言,所以打算用 Python写这个解释器。Python代码看起来很像伪代码,所以即使你不认识 Python,你也能理解它。解析可以通过一套从头开始实现的解析器组合完成(在本系列的下一篇文章中会有解释)。除了sys(用于I/O)、re(用于解析正则表达式)以及unittest(用于确保一切工作正常)库,没有使用其他额外的库。
IMP 语言
在开始写之前,我们先来讨论一下将要解释的语言。IMP是拥有下面结构的最小命令语言:
赋值语句(所有变量都是全局的,而且只能存储整数):
Python
1
x := 1
条件语句:
Python
1
2
3
4
5
if x = 1 then
y := 2
else
y := 3
end
while循环:
Python
1
2
3
while x < 10 do
x := x + 1
end
复合语句(分号分隔):
Python
1
2
x := 1;
y := 2
OK,所以它只是一门工具语言,但你可以很容易就把它扩展成比Lua或python更有用的语言。我希望能把这份教程能保持尽量简单。
下面这个例子是计算阶乘的程序:
Python
1
2
3
4
5
6
n := 5;
p := 1;
while n > 0 do
p := p * n;
n := n - 1
end
IMP没有读取输入的方式,所以初始状态必须是在程序最开始写一系列的赋值语句。也没有打印结果的方式,所以解释器必须在程序的结尾打印所有变量的值。
解释器的结构
解释器的核心是“中间表示”(Intermediate representation,IR)。这就是如何在内存中表示IMP程序。因为IMP是一个很简单的语言,中间表示将直接对应于语言的语法;每一种表达和语句都有对应的类。在一种更复杂的语言中,你不仅需要一个“语法表示”,还需要一个更容易分析或运行的“语义表示”。
解释器将会执行三个阶段:
将源码中的字符分割成标记符(token)
将标记符组织成一棵抽象语法树(AST)。抽象语法树就是中间表示。
评估这棵抽象语法树,并在最后打印这棵树的状态
将字符串分割成标记符的过程叫做“词法分析”,通过一个词法分析器完成。关键字是很短,易于理解的字符串,包含程序中最基本的部分,如数字、标识符、关键字和操作符。词法分析器会除去空格和注释,因为它们都会被解释器忽略。

实际执行这个解析过的抽象语法树的过程称为评估。这实际上是这个解析器中最简单的部分了。
本文会把重点放在词法分析器上。我们将编写一个通用的词汇库,然后用它来为IMP创建一个词法分析器。下一篇文章将会重点打造一个语法分析器和评估计算器。
词汇库
词法分析器的操作相当简单。它是基于正则表达式的,所以如果你不熟悉它们,你可能需要读一些资料。简单来说,正则表达式就是一种能描述其他字符串的特殊的格式化的字符串。你可以使用它们去匹配电话号码或是邮箱地址,或者是像我们遇到在这种情况,不同类型的标记符。
词法分析器的输入可能只是一个字符串。简单起见,我们将整个输入文件都读到内存中。输出是一个标记符列表。每个标记符包括一个值(它代表的字符串)和一个标记(表示它是一个什么类型的标记符)。语法分析器会使用这两个数据来决定如何构建一棵抽象语法树。
由于不论何种语言的词法分析器,其操作都大同小异,我们将创建一个通用的词法分析器,包括一个正则表达式列表和对应的标签(tag)。对每一个表达式,它都会检查是否和当前位置的输入文本匹配。如果匹配,匹配文本就会作为一个标记符被提取出来,并且被加上该正则表达式的标签。如果该正则表达式没有标签,那么这段文本将会被丢弃。这样免得我们被诸如注释和空格之类的垃圾字符干扰。如果没有匹配的正则表达式,程序就要报错并终止。这个过程会不断循环直到没有字符可匹配。
下面是一段来自词汇库的代码:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-
import sys
import re
def lex(characters, token_exprs):
pos = 0
tokens = []
while pos < len(characters):
match = None
for token_expr in token_exprs:
pattern, tag = token_expr
regex = re.compile(pattern)
match = regex.match(characters, pos)
if match:
text = match.group(0)
if tag:
token = (text, tag)
tokens.append(token)
break
if not match:
sys.stderr.write('Illegal character: %sn' % characters[pos])
sys.exit(1)
else:
pos = match.end(0)
return tokens
-
注意,我们遍历正则表达式的顺序很重要。lex会遍历所有的表达式,然后接受第一个匹配成功的表达式。这也就意味着,当使用词法分析器时,我们应当首先考虑最具体的表达式(像那些匹配算子(matching operator)和关键词),其次才是比较一般的表达式(像标识符和数字)。
词法分析器
给定上面的lex函数,为IMP定义一个词法分析器就非常简单了。首先我们要做的就是为标记符定义一系列的标签。IMP只需要三个标签。RESERVED表示一个保留字或操作符。INT表示一个文字整数。ID代表标识符。
Python
1
2
3
4
5
-
import lexer
RESERVED = 'RESERVED'
INT= 'INT'
ID = 'ID'
-
接下来定义词法分析器将会用到的标记符表达式。前两个表达式匹配空格和注释。它们没有标签,所以 lex 会丢弃它们匹配到的所有字符。
Python
1
2
3
-
token_exprs = [
(r'[ nt]+',None),
(r'#[^n]*', None),
-
然后,只剩下所有的操作符和保留字了。记住,每个正则表达式前面的“r”表示这个字符串是“raw”;Python不会处理任何转义字符。这使我们可以在字符串中包含进反斜线,正则表达式正是利用这一点来转义操作符比如“+”和“*”。
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-
(r':=', RESERVED),
(r'(',RESERVED),
(r')',RESERVED),
(r';', RESERVED),
(r'+',RESERVED),
(r'-', RESERVED),
(r'*',RESERVED),
(r'/', RESERVED),
(r'<=',RESERVED),
(r'<', RESERVED),
(r'>=',RESERVED),
(r'>', RESERVED),
(r'=', RESERVED),
(r'!=',RESERVED),
(r'and', RESERVED),
(r'or',RESERVED),
(r'not', RESERVED),
(r'if',RESERVED),
(r'then',RESERVED),
(r'else',RESERVED),
(r'while', RESERVED),
(r'do',RESERVED),
(r'end', RESERVED),
-
最后,轮到整数和标识符的表达式。要注意的是,标识符的正则表达式会匹配上面的所有的保留字,所以它一定要留到最后。
Python
1
2
3
-
(r'[0-9]+',INT),
(r'[A-Za-z][A-Za-z0-9_]*', ID),
]
-
既然正则表达式已经定义好了,我们还需要创建一个实际的lexer函数。
Python
1
2
-
def imp_lex(characters):
return lexer.lex(characters, token_exprs)
-
如果你对这部分感兴趣,这里有一些驱动代码可以测试输出:
Python
1
2
3
4
5
6
7
8
9
10
11
-
import sys
from imp_lexer import *
if __name__ == '__main__':
filename = sys.argv[1]
file = open(filename)
characters = file.read()
file.close()
tokens = imp_lex(characters)
for token in tokens:
print token
-
继续……
在本系列的下一篇文章中,我会讨论解析器组合,然后描述如何使用他们从lexer中生成的标记符列表建立抽象语法树。
如果你对于实现IMP解释器很感兴趣,你可以从这里下载全部的源码。
在源码包含的示例文件中运行解释器:
Python
1
-
python imp.py hello.imp
-
运行单元测试:
Python
1
-
python test.py
-
Ⅱ 如何python3中调用python2中的方法
在Windows操作系统上,Python一般被安装在C:Pythonxx的位置,这里xx代表版本号,例如,Python3.4就被安装在C:Python34文件夹中。你只需要把C:Pythonxx加入到系统环境变量中的path变量中,就可以从任何位置调用python解释器了。
OK,打开命令行窗口,输入python,就可以调用python解释器了。
要退出解释器,可以输入exit()函数或者quit()函数。
当然,还有另外一种方式调用python解释器直接解释执行Python语句,格式:python -c command [arg] ...,这里command就是要执行的python语句。
有一些脚本很有用,也可以直接作为模块来运行,格式: python -m mole [arg] ...,其中mole就是要运行的模块名字,当然这个模块必须要能够被Python运行时环境找到,也就是说它必须能够被import到,换句话说,相当于运行了import mole.
Ⅲ python3中,用os.system运行一个python2的程序(该程序调用一些模块),结果好像是调用了python3模块出错
环境变量里面设置的python3的路径,所以os调用的时候启动的python3,具体可以在命令行输入python --version看下版本号
Ⅳ python新手求解python2和python3的问题
python中python2和python3之间的转换方式如下:
一、放弃python 2.6之前的python版本
python 2.6之前的python版本缺少一些新特性,会给你的迁移工作带来不少麻烦。如果不是迫不得已还是放弃对之前版本的支持吧。
二、使用 2to3 工具对代码进行检查和转换
2to3是python自带的一个代码转换工具,可以将python2的代码自动转换为python3的代码。当然,不幸的是转换出的代码并没有对python2的兼容做任何的处理。所以我们并不真正使用2to3转换出的代码。执行2to3.py 查看输出信息,并修正相关问题。为了简化这个转换过程,这个脚本会将你的Python 2程序源文件作为输入,然后自动将其转换到Python 3的形式。

Ⅳ python3中使用部分python2中的一些代码报错怎样解决
Python 3中的str类型对象有点像Python 2中的unicode。
Python 3中的str是未编码的,str有一个encode方法,调用这个方法后将产生一个编码后的byte类型的字符串(这有点像Python 2中的str)。而byte类型的字符串支持解码操作。
Ⅵ 电脑已经装了python3,怎么兼容2
由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼容,如何让脚本在对应的Python版本上运行,这个是值得总结的。
对于Ubuntu 16.04 LTS版本来说,Python2(2.7.12)和Python3(3.5.2)默认同时安装,默认的python版本是2.7.12。

当python脚本需要python2运行时,只需在脚本前加上,然后运行py xxx.py即可。
#! python2
当python脚本需要python3运行时,只需在脚本前加上,,然后运行py xxx.py即可。
#! python3
就这么简单。
同时,这也完美解决了在pip在python2和python3共存的环境下报错,提示Fatal error in launcher: Unable to create process using '"'的问题。
当需要python2的pip时,只需
py -2 -m pip install xxx
当需要python3的pip时,只需
py -3 -m pip install xxx
python2和python3的pip package就这样可以完美分开了。
Ⅶ pycharm编译python3为什么不能直接计算数学结果
Ⅷ 如何在安装pip3以及第三方python库
环境
OS:10.12.3 (16D32) macOS Sierra
Python3: Python 3.6.1
1
2
3
什么是pip
Python之所以强大,其中一个原因是其丰富的第三方库。pip则是python第三方库的包管理工具。
由于在Mac上python2和python3是共存的。因而python3对应的包管理工具的命令就是:pip3
1
2
3
如何安装pip3
如果通过homebrew安装python3,那么pip3会同时安装。所以建议直接通过homebrew安装python3:
1
2
- $brew install python3//no need sudo1
- 如果你已经通过其他渠道安装了python3但是尚未安装pip3,那么需要通过以下步骤实现安装:12
https://pip.readthedocs.io/en/stable/installing/
- 上述的链接是官方给出的方法,但是有几个地方需要注意,最好按照我博客一步步来:12
https://bootstrap.pypa.io/get-pip.py
- 复制粘贴另存为链接中的文本,可以保存为get-pip.py。
- 注意:其中内容很多,必须等网页加载完再复制,然后通过已经安装的python3解释器解释执行另存为的文件123
- $python3 get-pip.py1
再次执行上述命令,显示:
- Requirement already up-to-date: pip in /usr/local/lib/python3.6/site-packages1
安装成功
如何安装第三方库
有了pip3以后,安装第三方库就容易多了,比如:
1
2
- $pip3 install requests
- Collecting requests
- Downloading requests-2.13.0-py2.py3-none-any.whl (584kB) 100% |████████████████████████████████| 593kB 298kB/s
- Installing collected packages: requests
- Successfully installed requests-2.13.0
Ⅸ 怎么启动python解释器
1.首先找到本地python安装位置,若找不到可直接搜索“python”,复制“python.exe”执行文件的所在目录,如下:

注意事项:
python2.x下为:print "Hello World"
python3.x下print需要加“()”:print ("Hello World")
Ⅹ python3解释器执行 d = {1:1,2:1}后查看d的结果是__
{1: 1, 2: 1}