operatorpython
‘壹’ python安装operator库方法
想要给你的程序安装一个第三方库,可以了解它的一些具体的形式才行。
‘贰’ 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
‘叁’ Python如何用operator判断3个元组相等Python3中,如何判断3个元组是否相同
摘要 tuple1 -- 比较的元组。
‘肆’ python 重载方法有哪些特点
python 的重载主要包括方法重载和运算符重载。1.python 方法重载: 其他的语言一般对于方法重载的话,主要是根据参数的类型不同或者是数量不同来区分同名的方法。而python则比较特殊,它本身是动态语言,方法的参数是没有类型的,当调用传值的时候才确定参数的类型,故对参数类型不同的方法无需考虑重载。对参数数量不同的方法,则(大多数情况下)可以采用参数默认值来实现。比如你可以定义函数的默认值:def info(x,y,z=1): pass2.python 运算符重载: 在C#中,我们通过使用关键字operator定义一个运算符方法,并定义与所在类相关的运算符行为。在 Python中,运算符重载的方式更为简单——每一个类都默认内置了所有可能的运算符方法,只要重写这个方法,就可以实现针对该运算符的重载。例如以下是重载加法操作:class Info(object): def __init__(self): self.a = 11 self.b = 22 def __add__(self,x): return self.a * self.b 上面的例子是重写了+操作符号,你也可以重载其他的运算符。比如你可以重载乘号运算符,感兴趣的话,可以自己写写代码。希望上面讲的2点能够让你对python重载有个简单的认识。有兴趣的可以关注下。
‘伍’ python里什么时候用operator模块
class A(object):
def __init__(self, b):
self.b = b
def __str__(self):
return "[%s, %s, %s]" % (self.b.attr1, self.b.attr2, self.b.attr3)
def __repr__(self):
return "[%s, %s, %s]" % (self.b.attr1, self.b.attr2, self.b.attr3)
class B(object):
def __init__(self, attr1, attr2, attr3):
self.attr1 = attr1
self.attr2 = attr2
self.attr3 = attr3
def __str__(self):
return "[%s, %s, %s]" % (self.attr1, self.attr2, self.attr3)
def __repr__(self):
return "[%s, %s, %s]" % (self.attr1, self.attr2, self.attr3)
‘陆’ 如何用Python添加数据库一列有序数字
通过例子来说明sorted的用法: 1. 对由tuple组成的List排序 Python代码 >>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10),] 用key函数排序(lambda的用法见 注释1) Python代码 >>> sorted(students, key=lambda student : student[2]) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] 用cmp函数排序 Python代码 >>> sorted(students, cmp=lambda x,y : cmp(x[2], y[2])) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] 用 operator 函数来加快速度, 上面排序等价于:(itemgetter的用法见 注释2) Python代码 >>> from operator import itemgetter, attrgetter >>> sorted(students, key=itemgetter(2)) 用 operator 函数进行多级排序 Python代码 >>> sorted(students, key=itemgetter(1,2)) # sort by grade then by age [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)] 2. 对由字典排序 Python代码 >>> d = {'data1':3, 'data2':1, 'data3':2, 'data4':4} >>> sorted(d.iteritems(), key=itemgetter(1), reverse=True) [('data4', 4), ('data1', 3), ('data3', 2), ('data2', 1)]
‘柒’ python如何对一组数排序
python对一组数排序的方法:
1、使用sorted()方法可以进行升序排序
2、可以operator模块方法进行多级排序
operator 模块方法允许多级排序。例如,可以先按 grade 排序,然后再按 age 排序
更多Python知识,请关注:Python自学网!!
‘捌’ python operator库
#第一种
importoperator
operator.temgetter
operator.attrgetter
#第二种
fromoperatorimportitemgetter,attrgetter
temgetter
attrgetter
这样应该能明白了吧
‘玖’ 什么时候采用python3 operator
operator.itemgetter函数
operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),下面看例子。
a = [1,2,3]
>>> b=operator.itemgetter(1) //定义函数b,获取对象的第1个域的值
>>> b(a)
2
>>> b=operator.itemgetter(1,0) //定义函数b,获取对象的第1个域和第0个的值
>>> b(a)
(2, 1)
要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。
sorted函数
Python内置的排序函数sorted可以对list或者iterator进行排序,该函数原型为:
sorted(iterable[, cmp[, key[, reverse]]])
参数解释:
(1)iterable指定要排序的list或者iterable,不用多说;
(2)cmp为函数,指定排序时进行比较的函数,可以指定一个函数或者lambda函数,如:
students为类对象的list,没个成员有三个域,用sorted进行比较时可以自己定cmp函数,例如这里要通过比较第三个数据成员来排序,代码可以这样写:
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
sorted(students, key=lambda student : student[2])
(3)key为函数,指定取待排序元素的哪一项进行排序,函数用上面的例子来说明,代码如下:
sorted(students, key=lambda student : student[2])
key指定的lambda函数功能是去元素student的第三个域(即:student[2]),因此sorted排序时,会以students所有元素的第三个域来进行排序。
有了上面的operator.itemgetter函数,也可以用该函数来实现,例如要通过student的第三个域排序,可以这么写:
sorted(students, key=operator.itemgetter(2))
sorted函数也可以进行多级排序,例如要根据第二个域和第三个域进行排序,可以这么写:
sorted(students, key=operator.itemgetter(1,2))
即先跟句第二个域排序,再根据第三个域排序。
(4)reverse参数就不用多说了,是一个bool变量,表示升序还是降序排列,默认为false(升序排列),定义为True时将按降序排列。
排序:
字典items()方法和iteritems()方法,是python字典的内建函数,分别会返回Python列表和迭代器
字典items()操作方法:
>>> x = {'title':'python web site','url':'www.iplaypy.com'}
>>> x.items()
[('url', 'www.iplaypy.com'), ('title', 'python web site')]
dict iteritems()操作方法:
>>> f = x.iteritems()
>>> f
<dictionary-itemiterator object at 0xb74d5e3c>
>>> type(f)
<type 'dictionary-itemiterator'> #字典项的迭代器
>>> list(f)
[('url', 'www.iplaypy.com'), ('title', 'python web site')]
字典.iteritems()方法在需要迭代结果的时候使用最适合,而且它的工作效率非常的高。
‘拾’ Python的基本术语有哪些
Python解释器
Python文本编辑器
Python代码运行助手
输入和输出
Python基础
数据类型和变量
字符串和编码
使用list和tuple
条件判断
循环
使用dict和set
函数
调用函数
定义函数
函数的参数
递归函数
高级特性
切片
迭代
列表生成式
生成器
迭代器
函数式编程
高阶函数
map/rece
filter
sorted
返回函数
匿名函数
装饰器
偏函数
模块
使用模块
安装第三方模块
面向对象编程
类和实例
访问限制
继承和多态
获取对象信息
实例属性和类属性
面向对象高级编程
使用__slots__
使用@property
多重继承
定制类
使用枚举类
使用元类
错误、调试和测试
错误处理
调试
单元测试
文档测试
IO编程
文件读写
StringIO和BytesIO
操作文件和目录
序列化
进程和线程
多进程
多线程
ThreadLocal
进程 vs. 线程
分布式进程
正则表达式
常用内建模块
datetime
collections
base64
struct
hashlib
hmac
itertools
contextlib
urllib
XML
HTMLParser
常用第三方模块
Pillow
requests
chardet
psutil
virtualenv
图形界面
网络编程
TCP/IP简介
TCP编程
UDP编程
电子邮件
SMTP发送邮件
POP3收取邮件
访问数据库
使用SQLite
使用MySQL
使用SQLAlchemy
Web开发
HTTP协议简介
HTML简介
WSGI接口
使用Web框架
使用模板
异步IO
协程
asyncio
async/await
aiohttp