1 基础
1.1 数**
整数 2(不区分long和int,py中整数类型可以任意长)
浮点型 3.23、52.3E-4
复数 (2.3-4.6j)
1.2 字符串
由Unicode标准支持的语言,默认所有的字符串的编码是Unicode,在py中没有仅仅使用ASCII的字符串,因为Unicode是ASCII的超集,若需要严格使用ASCII编码的字节流,可用str.encode(“ascii”)
1.3 引号
py中,单引号和双引号的使用完全相同,当使用三引号的时候,可以指示一个多行的字符串 (相当于一段话),在三引号内 可以使用单引号和双引号
1.4 转义序列
当使用单引号表示字符串中存在引号时,可使用’代替
如 'what\‘s your name?'
当使用双引号表示字符串中存在引号时,可使用’代替
如 "what\\‘s your name?"
字符串换行: “\n”
结尾加’'表示下一行继续
(自然字符串)如果字符串中需要带特殊含义的字符,需要在字符串前加r或者R,r"a\n"
1.4 format方法
字符串拼接时可将其他类型参数自动转义成字符串。
使用示例:
age=25
name='abc'
print('{0} is {1} years old'.format(name,age))
输出:abc is 25 years old
也可以用另一种写法
'{name} wrote {book}'.format(name='Swaroop', book='A Byte of Python')
输出:'Swaroop wrote A Byte of Python'
1.5 变量与标识符
变量:一种既可以存储信息又可以对信息进行操作的标识符
标识符:标识某样东西的名字
-
标识符的第一个字符必须是字母表中的字符(大写或小写)或者下划线。
-
标识符的其他部分可有字母(大写或小写)、下划线、数字组成。
-
标识符名称大小写敏感。
变量的基本数据类型为数字和字符串。
py中使用变量时只需要赋值,不需要声明或定义数据类型。
1.6 逻辑行和物理行
物理行指编程时所看见的语句,逻辑行指py看见的单个语句,py假定每个物理行对应一个逻辑行。(建议每行只使用一个语句)),也可使用分号表示一个语句的结束。
1.7 缩进
在行首的空白(空格和制表符)用来决定逻辑行缩进的层次,同一层次的语句必须有相同的缩进.
注:空格和制表符不可同时使用,会造成在跨越不同平台的时候无法正常工作。
py使用缩进来代表代码块,不适用括号(if while for)
2 操作符和表达式
2.1 操作符
+ | 3+5=8 |
---|---|
- | 5-3=2 |
* | 2*3=6 |
/ | 6/2=3 |
** | 3**4=81 |
// | 9//2=4 |
% | 4%3=1 |
<< | 按位运算,二进制数左移两位 高位丢弃,低位补零 |
>> | 把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数 |
& | 两数相应未都为1,结果为1,否则为0 |
| | 两数相应只要有一个为1,结果为1,否则为0 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-1 |
< | 判断是否小于,返回bool值 |
> | 判断是否大于,返回bool值 |
<= | 判断是否小于等于,返回bool值 |
>= | 判断是否大于等于,返回bool值 |
== | 判断是否等于,返回bool值 |
!= | 判断是否不等于,返回bool值 |
and | and前后只要有一个为false,返回false,两者都为true,返回true |
or | 只要有一个为true,就返回true |
3 控制流
3.1 if语句
表示判断,若满足if后的条件,执行if内的语句
例: if a==b:
print(a)
elif a>b:
print(b)
else:
print(a+b)
3.2 while
循环执行,只要在一个条件为真的情况下,while语句就会一直重复执行一个语句,
while(true):
print("abc")
else:
print("cba")
3.3 for循环
在一序列的对象上迭代,即逐一使用序列中的每 个项目。
for i in range(1,5):
print(i)
3.4 break 和continue
break语句是用来种植循环把语句的,若从for或while终止,else例也不执行。
continue,跳过当前循环内剩余的语句,直接执行下一次循环
4 函数
函数是重用的程序段。它们允许你给一个语句块一个名称,然后你用这个名字可 以在你的程序的任何地方,任意多次地运行这个语句块。这被称为调用函数。
例:
def a(x,y):
print(x+y)
4.1 全局变量
如果你想要为一个定义在函数外的变量赋值,那么你就得告诉 Python 这个变量 名不是局部的,而是全局的。使用global。
例:
x=1
def a():
global x
x=2
print(x)
a()
print(x)
4.3 非局部变量
例:
def a():
x=2
print(x)
def b():
nonlocal x
x=5
b()
print(x)
4.4 默认参数值
如果用户不想要为这些参数 提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。
例:
def a(x,y=1):
print(x+y)
a(1)
a(1,2)
注:只有最后那些参数可以设置默认参数值。
4.5 关键参数
如果你的某个函数有许多参数,而你只想指定其中的一部分,那么你可以通过命 名来为这些参数赋值 —— 这被称作关键参。
例:
def a(x,y=1,z=2):
print(x+y+z)
a(3,7)
a(3,c=5)
a(c=1,a=1)
4.6 VarArgs参数
想定义一个能获取任意个数参数的函数,这可通过使用 * 号来实现。
例:
def a(x=0,*y,**z):
print(x,y,z)
a(1,2,3,q=1,d=2)
在这写参数里 x的赋值为1;*y的赋值为2,3;**z的赋值为q=1,d=2
4.7 keyword-only参数
如果想指定特定的关键参数为 keywor-only 而不是位置参数,可以在带星的参数 后申明。
例:
def a(x=0,*y,z):
print(x,y,z)
a(1,2,3,z=1)
4.8 return
return 语句用来从一个函数返回即跳出函数。我们也可选是否从函数返回一个值。
def a(x):
return x
print(a(1))
注:无返回值的return =return None
4.9 文档字符串 DocStrings
DocStrings 是一个重要的工具,由于它帮助你的程序文档更加简单易懂,你应该尽量 使用它。
例:
def a():
'''aaaaa
aaaaa'''
print("bbb")
a()
print(a._doc_)
输出为:
bbb
aaaaa
aaaaa
5 模块
编写模块有各种各样的方法,但最简单的方法就是创建以 .py 为扩展名的文件, 在文件中包含函数和变量。 模块可以从另外一个程序导入来使用其函数的功能。
例:
import sys
def a():
for i in sys.argv:
print(i)
5.1 按字节编译的.pyc文件
导入一个模块相对来说是一个比较费时的事情,所以 Python 做了一些技巧,以 便使输入模块更加快一些。一种方法是创建按字节编译的文件,这些文件以.pyc 作为 扩展名。字节编译的文件与 Python 变换程序的中间状态有关。这些.pyc 文件通常与.py 文件相同的方式在相同路径被创建。
5.2 from…import…语句
如果你想要直接输入 argv 变量到你的程序中(避免在每次使用它时打 sys.),那 么你可以使用 from sys import argv 语句。如果你想要输入所有 sys 模块使用的名字, 那么你可以使用 from sys import * 语句。这对于所有模块都适用。注:__无法通过from…import *导入
5.3 模块的_name_
当一个模块第一次输入时,主块会被运行,可通过使用_name_来实现只在程序本身被使用的时候运行主块,而被其他模块输入时不运行主块。
例:
if _name_=='_main_':
print("a")
else:
print("b")
5.4 dir函数
dir()函数方法可返回该模块包含的所有标识符(函数,类和变量)
5.5 包
包是模块的文件夹,有一个特殊的 init.py 文件,用来表明这个文件夹是特殊 的因为其包含有 Python 模块。
6 数据结构
6.1 列表
list 是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项 目。可以增加 或删除项目,我们说列表是可变的数据类型,即这种类型是可以被改变的。
例:
shoplist = ['apple', 'mango', 'carrot', 'banana']
6.2 元组
元组用来将多样的对象集合到一起。元组是不可变的,即不可修改元组,元组通过圆括号中用逗号分隔的项目定义。
例:
zoo = ('python', 'elephant', 'penguin')
注:当元组只有一个元素时,应在第一个元素后加逗号,例:
zoo=('python',)
6.3 字典
我们把 键(名字)和值(详细情况)联系在一起。注意,键必须是唯一的,注意,你只能使用不可变的对象(比如字符串)来作为字典的键,但是你可以把 不可变或可变的对象作为字典的值。基本说来就是,你应该只使用简单的对象作为 键。
字典不是序列,是容器类对象
python3.6以后 字典也是有顺序的
例:
abc={
'a':a,
'b':b,
'c':c
}
6.4 序列
列表,元组和字符串都是序列,序列的主要特点是所成员检验和索引操作符。索引操作符让我们可以直接从序列中抓取一个特定项目。
上面提到的三种类型的序列 —— 列表、元组和字符串,也有切片操作,切片操 作让我们取出序列的薄片。
切片操作符中的第一个数(冒号之前)表示切片开始的位置,第二个数(冒号之 后)表示切片到哪里结束。如果不指定第一个数,Python 就从序列首开始。如果没有 指定第二个数,则 Python 会停止在序列尾。注意,返回的序列从开始位置开始,刚 好在结束位置之前结束。即开始位置是包含在序列切片中的,而结束位置被排斥在切 片外。 即所谓的包头不包尾。
也可以给切片规定第三个参数,就是切片的步长(默认步长是 1)。例:
shoplist = ['apple', 'mango', 'carrot', 'banana']
shoplist[::1] =['apple', 'mango', 'carrot', 'banana']
shoplist[::2] =['apple', 'carrot']
shoplist[::3] =['apple', 'banana']
shoplist[::-1]=['banana', 'carrot', 'mango', 'apple']
6.5 集合
集合是没有顺序的简单对象的聚集。当在聚集中一个对象的存在比其顺序或者出现的次数重要是用集合。使用集合可以检查是否是成员,是否是另一个集合的子集,得到两个集合的交集等等。
例:
bri = set(['brazil', 'russia', 'india'])
6.5 引用
当你创建一个对象并给它赋一个变量的时候,这个变量仅仅引用那个对象,而不 是表示这个对象本身!也就是说,变量名指向你计算机中存储那个对象的内存。这被 称作名称到对象的绑定。
例:
a=['a','b','c']
b=a
del a[0]
print(a)
print(b)
输出:
['b','c']
['b','c']
a=['a','b','c']
b=a[:]
del a[0]
print(a)
print(b)
输出:
['b','c']
['a','b','c']
注:如果你想要复制一个列表 或者类似的序列或者其他复杂的对象(不是如整数那样的简单对象),那么你必须使 用切片操作符来取得拷贝。如果你只是想要使用另一个变量名,两个名称都引用同一 个对象。
7 面向对象编程*****
类和对象是面向对象编程的两个主要方面。类创建一个新类型,而对象是这个类 的实例。这类似于你有一个 int 类型的变量,这存储整数的变量是 int 类的实例(对 象)。
对象可以使用普通的属于对象的变量存储数据。属于一个对象或类的变量被称为 域。对象也可以使用属于类的函数来具有功能。这样的函数被称为类的方法。这些术 语帮助我们把它们与孤立的函数和变量区分开来。域和方法可以合称为类的属性。 域有两种类型 —— 属于每个实例/类的对象或属于类本身。它们分别被称为实例 变量和类变量。 类使用 class 关键字创建。类的域和方法被列在一个缩进块中。
7.1 self
类的方法与普通的函数只有一个特别的区别 —— 它们必须有一个额外的第一个 参数名称,但是在调用这个方法的时候你不为这个参数赋值,Python 会提供这个值。 这个特别的变量指对象本身,按照惯例它的名称是 self。
假如你有一个类称为 MyClass 和这个类的一个实例 MyObject。当 你调用这个对象的方法 MyObject.method(arg1, arg2) 的时候,这会由 Python 自动转为 MyClass.method(MyObject, arg1, arg2)—— 这就是 self 的原理了。
例:
class Person:
def __init__(self,a,b,c):
self.a=a
self.b=b
self.c=c
def sayhi(self):
print('hi~',self.a)
p=Person('1',2,3)
p.sayhi()
这里__init__相当于java中的构造函数,在类的一个对象被建立时,马上运行,用来对你的对象做一些你希望的初始化。
7.2 类和对象变量的区分****
有两种类型的域 —— 类的变量和对象的变量,它们根据是类还是对象拥有这个 变量而区分。 类的变量由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以 当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。 对象的变量由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷 贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称, 但是是互不相关的。通过一个例子会使这个易于理解。
class a:
b=0
def __init(self,c):
self.c=c
a.b+=1
def __del__(self):
a.b-=1
def sayhi(self):
print('{0}'.format(self.c))
@staticmethod
#静态方法 类和对象都可调用,不需要传self,实际上是属于类的方法
def howMany():
print('{0}'.format(a.b))
x=a('1')
x.sayhi()
a.howMany()
y=a('2')
y.sayhi()
a.howMany()
del x
del y
a.howMany()
输出:
1
1
2
2
0
howMany 实际上是属于类而不是对象的方法。这意味着我们或者可以定义类方 法或者可以定义静态方法,这取决于我们是否需要知道我们是那个类的部分。既然我 们不需要这样的信息,就需要将其定义为静态方法。
上例中b属于a类的域(参数),当一个实例化对象操作b后,其他实例化对象获取的值也会发生变化。而self.c属于实例化对象的域,当他修改时 对其他对象不会有影响。
__del__在对象消逝的时候被调用,对象消逝即对象不再被使用,很难保证这个方法究竟什么时候运行,可使用del语句结束对象,这时候__del__就会被运行
注:py中所有的类成员都是公共的,所有的方法都是有效的,除__开头表示私有变量。
7.3 继承
假设你想要写一个程序来记录学校之中的教师和学生情况。他们有一些共同属 性,比如姓名、年龄和地址。他们也有专有的属性,比如教师的薪水、课程和假期, 学生的成绩和学费。 你可以为教师和学生建立两个独立的类来处理它们,但是这样做的话,如果要增 加一个新的共有属性,就意味着要在这两个独立的类中都增加这个属性。这很快就会 显得不实用。 一个比较好的方法是创建一个共同的类称为 SchoolMember 然后让教师和学生的 类继承这个共同的类。即它们都是这个类型(类)的子类型,然后我们再为这些子类 型添加专有的属性。 使用这种方法有很多优点。如果我们增加/改变了 SchoolMember 中的任何功能, 它会自动地反映到子类型之中。例如,你要为教师和学生都增加一个新的身份证
域,那么你只需简单地把它加到 SchoolMember 类中。然而,在一个子类型之中做 的改动不会影响到别的子类型。另外一个优点是你可以把教师和学生对象都作为 SchoolMember 对象来使用,这在某些场合特别有用,比如统计学校成员的人数。一 个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的 实例,这种现象被称为多态现象。 另外,我们会发现在重用父类的代码的时候,我们无需在不同的类中重复它。而 如果我们使用独立的类的话,我们就不得不这么做了。 在上述的场合中,SchoolMember 类被称为基本类或超类。而 Teacher 和 Student 类被称为导出类或子类。
例:
class base:
def __Init__(self,a,b):
self.a=a
self.b=b
def tell(self):
print('{0},{1}'.format(self.a,self.b))
class x(base):
def__init__(self,a,b,c):
base.__init__(self,a,b)
self.c=c
def tell(self):
base.tell(self)
class y(base):
def__init__(self,a,b,d):
base.__init__(self,a,b)
self.d=d
def tell(self):
base.tell(self)
t=x('q',w,e)
t.tell
s=y('a',s,d)
s.tell
输出:
qw
as
我们把基本类作为一个元组跟在定义类时的类名后,我们注意到基本类的 init 方法专门使用 self 变量调用,这样我们就 可以初始化对象的基本类部分。
在我们使用SchoolMember类的tell方法的时候,我们把Teacher和Student 的实例仅仅作为 ,在这个例子中,我们调用了子类型的 tell 方法,而不是 SchoolMember 类 的 tell 方法。可以这样来理解,Python 总是首先查找对应类型的方法,在这个例子中 就是如此。如果它不能在导出类中找到对应的方法,它才开始到基本类中逐个查找。 基本类是在类定义的时候,在元组之中指明的。 SchoolMember 的实例。
如果在继承元组中列了一个以上的类,那么它就被称作多 重继承。
7.4 将对象写入文件存储
例:
import pickle
afile='shoplist.data'
shoplist=['x','y','z']
f=open(shoplistfile,'wb')
pickle.dump(shoplist,f)
f.close()
del shoplist
f=open(shoplistfile,'rb')
storedlist=pickle.load(f)
print(storedlist)
为了在文件里储存一个对象,首先以写,二进制模式打开一个 file 对象,然后调 用 pickle 模块的 dump 函数,这个过程称为 pickling 。 接下来,我们用 pickle 模块的返回对象的 load 函数重新取回对象。这个过程称之 为 unpickling 。
8 异常捕获
py中的异常捕获主要用try…except.
try:
text = input('Enter something --> ')
except EOFError:
print('Why did you do an EOF on me?')
except KeyboardInterrupt:
print('You cancelled the operation.')
else:
print('You entered {0}'.format(text))
.引发异常主要用raise
例:
try:
if a<3:
raise ShortInputException(len(text),3)
except ShortInputException as ex:
print('ShortInputException The input was {0} long, excepted atleast {1}'.format(ex.length, ex.atleast))
当你无论如何都要执行某命令时,可用finally块来完成。
例:
try:
----
except:
print('报错了')
finally:
#即使出现异常也要执行完finally里的代码块程序才会停止
特殊函数
lambda
lam=lambda x : x+3
lam(2)
map
m=map(lambda x: x+3,range(10))
a=[1,2,3]
b=[4,5,6]
c=[7,8,9]
r=map(lambda x,y,z:x+y+z,a,b,c)
filter
过滤器
lst=[-1,2,3,4,5]
r=list(filter(lambda x:x>0,lst))
生成器与迭代器
生成器
生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。
生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器。
要创建一个generator,有很多种方法,第一种方法很简单,只有把一个列表生成式的[]中括号改为()小括号,就创建一个generator
#列表生成式
lis = [x*x for x in range(10)]
print(lis)
#生成器
generator_ex = (x*x for x in range(10))
print(generator_ex)
结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object <genexpr> at 0x000002A4CBF9EBA0>
用生成器创建斐波那契函数:
def fib(max):
n,a,b=0,0,1
while n<max:
yield b
a,b=b,a+b;
n+=1
lst=[i for i in fib(10)]
生成器表达式:
>>> # 列表解析生成列表
>>> [ x ** 3 for x in range(5)]
[0, 1, 8, 27, 64]
>>>
>>> # 生成器表达式
>>> (x ** 3 for x in range(5))
<generator object <genexpr> at 0x000000000315F678>
>>> # 两者之间转换
>>> list(x ** 3 for x in range(5))
[0, 1, 8, 27, 64]
迭代器
个实现了iter方法的对象是可迭代的,一个实现next方法并且是可迭代的对象是迭代器。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
所以一个实现了iter方法和next方法的对象就是迭代器。
生成器都是Iterator对象,但list、dict、str虽然是Iterable(可迭代对象),却不是Iterator(迭代器)。
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。