VERDVANA'S BLOG Verdvana

Python语法与实例


1 前言

        ASIC设计中需要用到脚本语言(Perl、Python、Shell等),有C语言基础的话Python好上手一些。


2 基础语法

2.1 编码

        默认情况下Python3源码文件以UTF-8编码,所有字符串都是unicode字符串。

2.2 标识符

        标识符由字母、数字、下划线组成,区分大小写,但不能以数字开头。可以使用中文作为变量名。

        以下划线开头的标识符是有特殊含义的:

  • 以单下划线开头的代表不能直接访问的类属性,须通过类提供的接口访问;
  • 以双下划线开头的代表雷的私有成员;
  • 以双下划线开头和结尾的代表Python里特殊方法专用的标识。

2.3 保留字符

        就是关键字,只包含小写字母:

img1

2.4 行和缩进

        Python代码块不能用“{}”来控制类、函数以及其他逻辑判断,而是用缩进来写模块。缩进的空白数量是可变的,但所有代码块语句必须包含相同的缩进空白数量,必须严格执行,“Tab”和空格键不能混用。

        Python语句中一般以新一行作为语句的结束符,但可以用多行连接符“\”将一行的语句分为多行“

    a = b + \
        c + d \
        - 30

        语句中包含“[]”、”{}”、“()”就不需要使用多行连接符。

        Python也可以同一行显示多条语句,语句之间用“;”分开:

print("硬件不行了!"); print("辣当蓝啦");

2.5 引号

        Python可以使用引号(’)、双引号(”)、三引号(’'’或””“)来表示字符串。引号的开始和解书必须是相同类型的。其中三引号用于多行字符标注:

name            = '岑小康'
age             = “18”
characteristic  = '''爱穿
                    横条纹'''

2.6 注释

        单行注释用“#”,多行注释首尾用三引号。


3 变量与数据类型

        Python有五个标准的数据类型:

  • Number(数字):
    • int(有符号长整型);
    • bool(布尔型);
    • float(浮点型);
    • complex(复数);
  • String(字符串);
  • List(列表);
  • Tuple(元组);
  • Set(集合);
  • Dictionary(字典)。

        其中:

  • 不可变数据类型:
    • Number;
    • String;
    • Tuple;
  • 可变数据类型:
    • List;
    • Dictionary;
    • Set。

        内置的“type()”函数可以用来查询变量所指的对象类型:

a = 111
type(a)

        返回:

<class 'int'>

        此外还可以用“isinstance()”来判断:

a = 111
isinstance(a,int)

        返回:

True

3.1 变量赋值

        Python中的变量赋值不需要类型声明,会根据变量自动匹配类型。每个变量在内存中创建,在使用前必须被赋值,变量赋值以后该变量才会被创建。

        用等号“=”给变量赋值,左边是变量名,右边是存储在变量中的值:

name    = 'Hamilton'
pi      = 3.14
cont    = 60

        其中“name”文字符串变量,“pi”为浮点型变量,“cont”为整型变量。

        Python也允许同时为多个变量赋值:

a=b=c=1
d,e,f=1,2,'Hamilton'

        其中“a”、“b”、“c”、“d”、“e”为整型变量,“f”为字符串变量。

3.2 Number

        数字数据类型用于存储数值,数据类型不允许改变。对变量赋值时对象直接被创建:

var1 = 1
var2 = 2
str  = f"one {var1}"
a,b,c = 0,1,2

        也可以使用“del”语句删除对象:

del var
del var1,var2

        数值类型举例:

int long float complex
10 3426576L 0.0 4.14j
200 -0x13152L 15.66 45.j
-570 0xDEFABCEAL -213.8 9.322e-36j
-0o422 -840932750L 32.3e+18 .876j
-0x443 347653L -90 4.7e-7j
0x19 0281L 70.2e-12 -.65+0j

        其中,复数由实部和虚部组成,可以用“a+bj”或“complex(a,b)”表示,复数的实部和虚部都是浮点型。

        数字类型转换:

int(x)          #将x转换为整数;
float(x)        #将x转换为一个浮点数;
complex(x)      #将x转换到一个复数,实数部分为x,虚数部分为0;
complex(x,y)    #将x和y转换到一个复数,实数部分为x,虚数部分为y,x和y是数字表达式。

        数学函数:

函数 描述
abs(x) 返回数字的绝对值,如abs(-10)返回10
ceil(x) 返回数字的上入整数,例如ceil(4.1)返回5
exp(x) 返回e的x次幂
fabs(x) 返回数字的绝对值,如abs(-10)返回10.0
floor(x) 返回数字的下舍取整,如floor(4.9)返回4
log(x[,y]) 返回对数,如log(e)返回1.0,log(100,10)返回2.0
log10(x) 返回以10为底x的对数
max(x1,x2,…) 返回给定参数的最大值
min(x1,x2,…) 返回给定参数的最小值
modf(x) 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示
pow(x,y) x**y运算后的值
round(x[,n]) 返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数
sqrt(x) 返回x的平方根

        随机函数:

函数 描述
choice(seq) 从序列的元素中随机挑选一个元素,比如range(10),从0-9中随机挑选一个种子
randrange([start,]stop[,step]) 从指定范围内,按指定基数递增的集合中获取一个随机数,基数默认值为1
random() 随机生成一个实数,范围在[0,1)范围内
seed([x]) 改变随机数生成器种子seed
shuffle(lst) 将序列的所有元素随机排列
uniform(x,y) 随机生成下一个实数,它在[x,y]范围内

        三角函数:

函数 描述
acos(x) 返回x的反余弦弧度值
asin(x) 返回x的反正弦弧度值
atan(x) 返回x的反正切弧度值
atan2(y,x) 返回给定的x及y坐标值得反正切值
cos(x) 返回x的弧度的余弦值
hypot(x,y) 返回欧几里得范数sqrt(xx+yy)
sin(x) 返回x弧度的正弦值
tan(x) 返回x弧度的正切值
degrees(x) 将弧度转换为角度
radians(x) 将角度转换为弧度

        随机函数:

函数 描述
pi π
e e

3.3 String

        字符串由数组、字母和下划线组成。

        与C语言不同的是,Python字符串是不能被更改的

        可以使用反斜杠转义特殊字符,如果不想让反斜杠发生转义,可以在字符串前面添加一个“r”:

print('Mac\nBook')
print(r'Mac\nBook')

        结果为:

Mac
Book
Mac\nBook
转义字符 描述
\(出现在行尾) 续行符
\\ 反斜杠符号
\’ 单引号
\” 双引号
\a 响铃
\b Backspace
\000
\n 换行
\v 纵向制表符
\t 横向制表符
\r 回车
\f 换页
\oxxx 八进制数
\xyyy 十六进制
\other 其他的字符以普通格式输出

        字符串列表有两种取值顺序:

  • 从左至右索引,默认0开始,最大范围是字符串长度-1;
  • 从右至左索引,默认-1开始,最大范围是字符串开头。
N F A U D I O
0 1 2 3 4 5 6
-7 -6 -5 -4 -3 -2 -1

        若要从字符串中获取一段子字符串的话,可以使用“[头下标:尾下标]”来截取相应的字符串,获取的字符串包含头下标的字符,不包含尾下标的字符。下标可以为空,表示从头取到位。

        另外,“+”是字符串连接符,“*”是重复操作,也可以在截取时加入第三个参数,说明截取的步长:

str = 'Hello World!'
print str
print str[0]
print str[2:5]
print str[2:]
print str[6:10:2]
print str*3
print str+'wanglaowu'

        结果如下:

Hello World!
H
llo
llo World!
Wr
Hello World!Hello World!Hello World!
Hello World!wanglaowu

        Python支持格式化字符串的输出,与C语言语法一样:

符号 描述
%c 格式化字符及其ASCII代码
%s 格式化字符串
%d 格式化整数
%u 格式化无符号整型
%o 格式化无符号八进制数
%x 格式化无符号十六进制数
%X 格式化无符号十六进制数(大写)
%f 格式化浮点数字,可指定小数点后的精度
%e 用科学计数法
%E 同%e
%g %f和%e的简写
%G %f和%E的简写
%p 用十六进制数格式化变量的地址

        格式化操作符辅助指令:

符号 功能
* 定义宽度或小数点精度
- 用做左对齐
+ 在正数前面显示“+”号
<sp> 在正数前面显示空格
# 在八进制数前面显示“0”,在十六进制前面显示“0x”或“0X”
0 显示的数字前面填充“0”而不是默认的空格
% “%%”输出为“%”
(var) 映射变量(字典参数)
m.n. m是显示的最小总宽度,n是小数点后的位数(如果可用)

3.4 List

        列表是由一系列按特定顺序排列的元素组成,可以完成大多数集合类的数据结构实现,它支持字符、数字、字符串甚至可以包含列表(嵌套)。

3.4.1 创建list

        列表用“[]”标识,列表的截取和字符串的截取类似:

list = ['iPhone',768,2.23,'perl',88.1]  #['iPhone',768,2.23,'perl',88.1]
tinylist = ['Touch',990]                #['Touch',990]

print (list)                            #['iPhone',768,2.23,'perl',88.1]
print (list[0])                         #iPhone
print (list[-1])                        #88.1
print (list[1:3])                       #[768,2.23]
print (list[2:])                        #[2.23,'perl',88.1]
print (list*2)                          #['iPhone',768,2.23,'perl',88.1,'iPhone',768,2.23,'perl',88.1]
print (list+tinylist)                   #['iPhone',768,2.23,'perl',88.1,'Touch',990]

        如果参数为负,表示逆向读取:

list = [1,2,3,4]
list = list[-1::-1]                     
print (list)                            #[4,3,2,1]

3.4.2 list元素替换

        List的值可以二次更改,替换直接赋值:

name = ['小康','大康','中康']       # ['小康','大康','中康']
name[1] = '微康'                   # ['小康','微康','中康','微康]

        列表中添加或删除元素:

# 直接赋值修改
name = ['小康','大康']              # ['小康','大康']
# append添加在列表尾
name.append('中康')                 # ['小康','大康','中康'] 
# insert插在任意位置
name.insert(0,'微康')               # ['微康','小康','大康','中康']
# del删除任意位置元素
del name[1]                        # ['微康','大康','中康']
# pop不会直接删除列表中的元素
last = name.pop()                  # '中康'
name = name.pop()                  # ['微康','大康']
name = name.pop(1)                 # ['微康']
# remove根据元素值删除,只删除指定的第一个值
name.remove('微康')                # []

3.4.3 list管理

        列表管理的一些函数:

cars = ['bmw','audi','toyota','subaru'] # ['bmw','audi','toyota','subaru']
cars.sort()                             # ['audi','bmw','subaru','toyota']
cars.sort(reverse=True)                 # ['toyota','subaru','bmw','audi']
sorted(cars)                            # 仅排序,不改变原列表
cars.reverse()                          # 反向排列,不是按字母顺序
len(cars)                               # 列表长度:4

3.4.4 list复制

        要复制列表,可以创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引:

list_1 = ['bmw','audi','toyota','subaru']
list_2 = list_1[:]                      # list_1与list_2的内容完全相同,且为两个不同的列表

        不能直接复制,这样只是将新变量与已有变量相关联,指向的是同一个列表

3.4.5 list循环

        需要对列表中每个元素做相同的处理,可以用for循环:

cars = ['bmw','audi','toyota','subaru']
for car in cars:
    print (f"Car is {car}")             # 打印“Car is $car”

for car in cars[:3]:
    print car                           # 打印前三个元素

        可以使用range()函数创建数值列表:

# for和range产生数
for value in range(1,5)
    print (value)                       # 会换行打印1,2,3,4
# range产生数值列表
number = list (range(1,6))              # number为[1,2,3,4,5]
# range产生指定步长的数字列表
even_number = list (range(2,11,2))      # even_number为[2,4,6,8,10]

3.4.6 list推导式

        创建一个整数的平方为元素的列表可以通过上一小节中的range和for来产生:

squares = []
for value in range(1,11):
    squares.append(value ** 2)              # squares = [1,4,9,16,25,36,49,64,81,100]

        这样的方式包含了三四行代码,而列表推导式只需编写一行代码就能生成这样的列表。它将for循环和创建新元素的代码合并成一行,并自动追加新元素:

squares = [value**2 for value in range(1,11)]       # squares = [1,4,9,16,25,36,49,64,81,100]

3.4.7 list相关函数

        有几个Python函数可以处理数值列表:

digits = [1,2,34,567,8,90]
print min(digits)               # 1
print max(digits)               # 567
print sum(digits)               # 702

3.5 Tuple

        Tuple类似于List但不能二次赋值,相当于只读列表,用“()”标识。

dimensions = (200,50)

        构造包含1个和0个元素的元组比较特殊,所以有一些额外的语法规则,这是因为严格来说tuple是由逗号标识的

tup1 = ()
tup2 = (33,)

        Tuple也可以使用for循环遍历。

        Tuple的元素不能二次赋值,但是可以重新定义整个tuple。

3.6 Set

        集合(Set)是有一个或多个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。它的基本功能是进行成员关系测试和删除重复元素。

        可以使用大括号“{}”或“set()”函数创建集合,要创建空集合必须用“set()”函数而不是“{}”,因为“{}”是用来创建一个空字典。

set1 = {'Google','Amazon','Apple','Facebook','Amazon','Tahooo'}
print(set1)     #重复的元素被自动去掉

if 'Intel' in set1:
    print('Intel在集合中')
else:
    print('Intel不在集合中')

# set可以进行集合运算

a = set('iPod')
b = set('iMac')

print(a-b)  #a和b的差集
print(a|b)  #a和b的并集
print(a&b)  #a和b的交集
print(a^b)  #a和b中不同时存在的元素

        结果为:

{'Google','Amazon','Apple','Facebook','Tahooo'}
Intel不在集合中
{'P','o','d'}
{'i','P','o','d','M','a','c'}
{'i'}
{'P','o','d','M','a','c'}

3.7 Dictionary

        Dictionary是除列表以外Python中最灵活的内置数据结构类型。列表是有序的对象集合,字典是无序的对象集合。两者区别在于字典当中的元素是通过键来存取,而不是通过偏移存取。

        Dictionary用“{}”标识,字典由索引“key”和它对应的值“value”组成,“key”必须是唯一的,且必须使用不可变类型。构造函数“dict()”可以直接从键值对序列中构建字典:

dict = {}

dict['one'] = 'Macintosh'
dict[2] = 'PowerBook'

tinydict = {'iii':'iMac','4':'iBook','V':'PowerBook'}

print dict['one']
print dict[2]
print tinydict
print tinydict.keys()
print tinydict.values()

        结果为:

Macintosh
PowerBook
{'iii':'iMac','4':'iBook','V':'PowerBook'}
['iii','4','V']
['iMac','iBook','PowerBook']

        创建空字典用“{}”。

3.8 数据类型转换

        数据类型的转换,只需要将数据类型作为函数名即可。以下几个内置的函数可以执行数据类型之间的转换,这些函数返回一个新的对象,即转换的值:

函数 描述
int(x[,base]) 将x转换为一个整数
long(x[,base]) 将x转换为一个长整数
float(x) 将x转换为一个浮点数
complex(real [,imag]) 创建一个复数
str(x) 将对象x转换为字符串
repr(x) 将对象x转换为表达式字符串
eval(str) 用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s) 将序列s转换为一个元组
list(s) 将序列s转换为一个列表
set(s) 转换为可变集合
dict(d) 创建一个字典,d必须是一个序列(hey,value)元组
frozenset(s) 转换为不可变集合
chr(x) 将一个整数转换为一个字符
unichr(x) 将一个整数转换为Unicode字符
ord(x) 将一个字符转换为它的整数值
hex(x) 将一个整数转换为一个十六进制字符串
oct(x) 将一个整数转换为一个八进制字符串

4 运算符

4.1 算术运算符

运算符 描述 结果
+ 相加 10+20=30
- 相减或取负数 10-20=-10
* 相乘或返回一个被重复若干次的字符串 10*20=200
/ 相除 20/10=2
% 取余 20%10=0
** 2**3=8
// 取整除,返回商的整数部分(向下取整) 9//2=4 -9//2=-5

4.2 比较运算符

运算符 描述 实例
== 相等 10==20 返回False
!= 不等 10!=20 返回True
<> 不等于(python3已遗弃) 类似!=
> 大于 10>20 返回False
< 小于 10<20 返回True
>= 大于等于 10>=20 返回False
<= 小于等于 10<=20 True

4.3 赋值运算符

运算符 描述 实例
= 简单的赋值 c=a+b
+= 加法赋值 c+=a 等效于 c=c+a
-= 减法赋值 c-=a 等效于 c=c-a
*= 乘法赋值 c*=a 等效于 c=c*a
/= 除法赋值 c/=a 等效于 c=c/a
%= 取模赋值 c%=a 等效于 c=c%a
**= 幂赋值 c**=a 等效于 c=c**a
//= 取整数赋值 c//=a c等效于 =c//a
:= 海象运算符,可以在表达式内部为变量赋值 n := len(a)

4.4 位运算符

        跟Verilog里的位运算一样,就不举例了。

运算符 描述 实例
& 按位与  
| 按位或  
^ 按位异或  
~ 按位取反  
« 左移动,高位丢弃,低位补零  
» 右移动,低位丢弃,高位补零  

4.5 逻辑运算符

运算符 描述 实例
and 布尔与,两者有一个为False则返回False,否则返回后者的值 10and20 返回20
or 布尔或,前者非0,返回他本身的值,否则返回后者的值 10or20 返回10
not 布尔非,取反 not(10and20) 返回False

4.6 成员运算符

运算符 描述 实例
in 在指定序列中找到值返回true,否则返回False  
not in 与in相反  

4.7 身份运算符

运算符 描述 实例
is 判断两个标识符是否引用自同一个对象 x is y,类似id(x)==id(y),如果引用的是同一个对象则返回True,否则返回False
is not 与is相反  

4.8 运算符优先级

        以下表格列出了从最高到最低优先级的所有运算符:

运算符 描述
** 指数(最高)
~ + - 按位取反,一元加减
* / % // 乘除、取模和取整除
+ - 加法减法
» « 左移右移
& 位于
^ | 位运算符
<= >= <> 比较运算符
<> == != 等于运算符
= %= /= //= -= +- *= **= 赋值运算符
is is not 身份运算符
in not in 成员运算符
not and or 逻辑运算符

5 语句

5.1 输入语句

        执行下面语句则会等待用户输入:

input("输入xxx,按下Enter完成:")

5.2 输出语句

        print输出默认是换行的,如果要实现不换行,需要在末尾加“end=” “”:

x="a"
y="b"

print x
print y

print (x,end=" ")
print (y,end=" ")

        结果如下:

a
b
a b

5.3 导入语句

        Python用“import”或者“From…import”来导入相应的模块。

        将整个模块(somemodule)入,格式为:

import somemodule

        从某个模块中导入某个函数,格式为:

from somemodule import somefunction

        从某个模块中导入多个函数,格式为:

from somemodule import firstfunc, secondfunc, thirdfunc

        将某个模块中的全部函数导入,格式为:

from somemodule import *

5.4 条件运算符

        指定任何非0和非空(null)的值为True,0或null为False。if语句的判断条件可以用“>”、“<”、“==”、“>=”、“<=”来表示其关系:

if 判断条件1:
    执行语句1
elif 判断条件2:
    执行语句2
elif 判断条件3:
    执行语句3
else:
    执行语句4

        由于Python不支持switch语句,所以多个条件判断只能用elif实现,如果有多个条件需要町是判断,可以使用or,表示两个条件有一个成立时判断成功;使用and时,只有两个条件同时成立的情况下,判断成功。

        也可以在同一行的位置上使用if条件判断语句,如:

var = 100
if(var == 100) : print"var的值为100"
print "告辞!"

        运行结果:

var的值为100
告辞!

5.5 循环语句

        Python提供二for循环和while循环:

循环类型 描述
while 在给定的判断条件为True时执行循环体,否则退出循环
for 重复执行语句
嵌套循环 在while循环体中嵌套for循环

        Python支持以下循环控制语句:

控制语句 描述
break 在语句块执行过程中终止循环,并跳出整个循环
continue 在语句块执行过程中终止当前循环,跳出该次循环,执行下一次循环
pass pass是空语句,是为了保持程序结构的完整性

5.5.1 while语句

        和C语言类似:

while 判断条件:
    执行语句

test

graph LR
style A fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 10,5
style B fill:#ccf,stroke:#f66,stroke-width:2px,stroke-dasharray: 10,5
    A --> B;
    B --> C;
    C --> A;
{ signal: [
  { name: "clk",  wave: "p......|..." },
  { name: "bus",  wave: "x.34.5x|=.x",},
  { name: "wire", wave: "0.1..0.|.1." },
  {},
  { name: "clk",  wave: "p......|..." },
  { name: "bus",  wave: "x.34.5x|=.x",   data: "head body tail" },
  { name: "wire", wave: "0.1..0.|.1." }
]}