· 基础
python基础:
Python使用缩进来组织代码块。最好坚持使用4个空格的缩进。2种注释的方法:
- 单行注释符号:# (类似于c的//)
#coding=utf-8
#coding=gbk
- 批量、多行注释符号:三对单引号或三对双引号(”’ ”’ or “”” “”“)
'''
coding=utf-8
coding=gbk
'''
"""
coding=utf-8
coding=gbk
"""
- 单行注释符号:# (类似于c的//)
文件开头两行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行注释是为了告诉 Linux/OS X 系统,这是一个 Python 可执行程序,Windows 系统会忽略这个注释;
第二行注释是为了告诉 Python 解释器,按照 UTF-8 编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
· 数据类型和变量
整数
浮点数
字符串:str,不可变对象
布尔值(True/False,注意区分大小写)
空值(None)
变量
常量
1、字符串
有两种方式:
- 单引号’
- 双引号”
如果’或者”本身也是一个字符
- 用”或’括起来。如,”I’m OK”
- 转义字符
- -
2、变量
- 必须是大小写英文、数字和_的组合,不能数字开头。
- 区分大小写(C、C++也区分)
3、两种除法
/
精确的除法,结果为浮点数(无论是否整除)//
地板除,返回整数
4、注意
整数、浮点数都没有大小(存储字节个数)限制。无限大用inf表示。
5、检查变量类型的函数
isinstance(object, classinfo)
>>>a = 2
>>> isinstance (a,int)
True
>>> isinstance (a,str)
False
>>> isinstance (a,(str,int,list)) #是元组中的一个返回True
True
· 字符串和编码
几种编码:
ASCII编码:
由于计算机是美国人发明的,因此,最早只有 127 个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为 ASCII 编码,比如大写字母 A 的编码是 65,小写字母 z 的编码是 122。GB2312 编码:
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和 ASCII 编码冲突,所以,中国制定了 GB2312 编码,用来把中文编进去。Unicode:
Unicode 把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode 标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要 4 个字节)。现代操作系统和大多数编程语言都直接支持 Unicode。UTF-8 编码:
本着节约的精神,又出现了把 Unicode 编码转化为“可变长编码”的 UTF-8 编码。 UTF-8 编码把一个 Unicode 字符根据不同的数字大小编码成 1-6 个字节,常用的英文字母被编码成 1 个字节,汉字通常是 3 个字节,只有很生僻的字符才会被编码成 4-6 个字节。如果你要传输的文本包含大量英文字符,用 UTF-8 编码就能节省空间。
总结:
- 在计算机内存中,统一使用 Unicode 编码,当需要保存到硬盘或者需要传输的时候,就转换为 UTF-8 编码。
- 用记事本编辑的时候,从文件读取的 UTF-8 字符被转换为 Unicode 字符到内存里,编辑完成后,保存的时候再把 Unicode 转换为 UTF-8 保存到文件。
- 浏览网页的时候,服务器会把动态生成的 Unicode 内容转换为 UTF-8 再传输到浏览器。
python中字符和编码的转换
- ord() 字符到整数
- chr() 编码到字符
- bytes类型
- ’ABC’ str字符串类型 unicode编码
- b’ABC’ bytes类型 每个字符只占用一个字节
- encode()函数:指定编码
- ’ABC’.encode(‘ascii’):b’ABC’
- ‘中文’.encode(‘utf-8’):b’\xe4\xb8\xad\xe6\x96\x87’
- ‘中文’.encode(‘ascii’):报错
- len()函数:统计字符数
- len(‘中文’):2
- len(b’ABC’):3
- len(b’\xe4\xb8\xad\xe6\x96\x87’):6
- len(‘中文’.encode(‘utf-8’)):6
字符串格式化
和 C 语言是一致的,用%实现。举例如下:
>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'
格式化整数和浮点数还可以指定是否补 0 和整数与小数的位数:
>>> '%2d-%02d' % (3, 1)
' 3-01'
>>> '%.2f' % 3.1415926
'3.14'
如果你不太确定应该用什么, %s 永远起作用,它会把任何数据类型转换
为字符串:
>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'
· 列表 list和tuple
1. list:可变的有序表
list 里面的元素的数据类型也可以不同,也可以是另一个 list。
classmates = ['Michael', 'Bob', 'Tracy']
空的 list。
L = []
长度(len(L))为0访问:索引是从 0 开始的:
>>> classmates[0]
'Michael'
>>> classmates[1]
'Bob'
>>> classmates[2]
'Tracy'
>>> classmates[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
- 还可以用-1 做索引
>>> classmates[-1]
'Tracy'
>>> classmates[-2]
'Bob'
>>> classmates[-3]
'Michael'
>>> classmates[-4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
追加元素到末尾
classmates.append('Adam')
把元素插入到指定的位置
classmates.insert(1, 'Jack')
删除 list 末尾的元素
classmates.pop()
删除指定位置的元素
classmates.pop(1)
把某个元素替换成别的元素
classmates[1] = 'Sarah'
2. tuple:初始化之后不能修改
classmates = (‘Michael’, ‘Bob’, ‘Tracy’)
访问方式和list相同,不能修改。
在定义的时候, tuple 的元素就必须被确定下来
只有 1 个元素的 tuple 定义时必须加一个逗号,,来消除歧义:
t = (1,)
“可变”的tuple
tuple 的每个元素,指向永远不变。即指向’a’,就不能改成指向’b’,指向一个 list,就不能改成指向其他对象, 但指向的这个 list 本身是可变的!
>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])
字典dict和set
1. dict :key-value 存储方式(key不能重复)
用空间来换取时间。适合高速查找。
在其他语言中也称为 map,使用键-值(key-value)存储,具有极快的查找速度。
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95
- 由于一个 key 只能对应一个 value,所以,多次对一个 key 放入 value,后面的值会把前面的值冲掉。
- 如果 key 不存在, dict 就会报错。要避免 key 不存在的错误,有两种办法:
- 一是通过 in 判断 key 是否存在:
>>> 'Thomas' in d
False
- 通过 dict 提供的 get 方法,如果 key 不存在,可以返回 None,或者
自己指定的 value:
>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1
- 删除一个 key,用 pop(key)方法,对应的 value 也会从 dict 中删除:
>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}
2. set:一组 key 的集合,但不存储 value。(key不重复)
- 要创建一个 set,需要提供一个 list 作为输入集合:
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
- 重复元素在 set 中自动被过滤:
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
- 通过 add(key)方法可以添加元素到 set 中,可以重复添加,但不会有效
果:
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
- 通过 remove(key)方法可以删除元素:
>>> s.remove(4)
>>> s
{1, 2, 3}
各种结构(条件判断、循环……
1. 条件判断
if <条件判断 1>:
<执行 1>
elif <条件判断 2>:
<执行 2>
elif <条件判断 3>:
<执行 3>
else:
<执行 4>
2. 循环
- for 循环
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print(sum)
# range(101)就可以生成 0-100 的整数序列
sum = 0
for x in range(101):
sum = sum + x
print(sum)
- while 循环
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
· 函数
- 函数名:
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个
变量,相当于给这个函数起了一个“别名”:
>>> a = abs # 变量 a 指向 abs 函数
>>> a(-1) # 所以也可以通过 a 调用 abs 函数
1
- 定义函数:
在 Python 中,定义一个函数要使用 def 语句,依次写出函数名、括号、
括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值
用 return 语句返回。
如果没有 return 语句,函数执行完毕后也会返回结果,只是结果为 None。return None 可以简写为 return。
#自定义一个求绝对值的 my_abs 函数为例:
def my_abs(x):
if x >= 0:
return x
else:
return -x
- 空函数:
如果想定义一个什么事也不做的空函数,可以用 pass 语句:
def nop():
pass
- 调用函数:
如果你已经把 my_abs()的函数定义保存为 abstest.py 文件了,那么,可以在该文件的当前目录下启动 Python 解释器,用 from abstest import my_abs 来导入 my_abs()函数,注意 abstest 是文件名(不含.py 扩展名)。
from abstest import my_abs
- 参数检查:
Python 解释器会自动检查参数个数;
数据类型检查可以用内置函数 isinstance()实现:
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
- 返回多个值:
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
返回的其实是一个tuple。在语法上,返回一个 tuple 可以省略括
号,而多个变量可以同时接收一个 tuple,按位置赋给对应的值,所以,
Python 的函数返回多值其实就是返回一个 tuple,但写起来更方便。
>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print(x, y)
151.96152422706632 70.0
· 函数参数
1. 默认参数
- 必选参数在前,默认参数在后,否则 Python 的解释器会报错。
def power(x, n=2):
while n > 0:
n = n - 1
s = s * x
return s
#当我们调用 power(5)时,相当于调用 power(5, 2)
>>> power(5)
25
>>> power(5, 2)
25
- 也可以不按顺序提供部分默认参数
def enroll(name, gender, age=6, city='Beijing'):
print('name:', name)
print('gender:', gender)
print('age:', age)
print('city:', city)
#调用(age采用默认参数,city为自定义值)
enroll('Adam', 'M', city='Tianjin')
- 默认参数必须指向不变对象!
def add_end(L=[]):
L.append('END')
return L
#调用结果:因为在下次调用的时候,默认参数的内容发生了改变,不是初始的[]
>>> add_end()
['END']
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
比较好的写法是:
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
#现在,无论调用多少次,都不会有问题:
>>> add_end()
['END']
>>> add_end()
['END']
2. 可变参数
当传入参数的个数是不确定的时候,可以的做法:把参数作为一个 list 或 tuple 传进来。但在调用的时候,需要先组装出一个 list 或 tuple。
可变参数就是传入的参数个数是可变的。利用可变参数,调用函数的方式就可以简化,输入的参数个数是任意的。
定义可变参数和定义一个 list 或 tuple 参数相比,仅仅在参数前面加了一个*号。在函数内部,参数 numbers 接收到的是一个 tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括 0 个参数。
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
>>> calc(1, 2)
5
>>> calc()
0
3、关键字参数
在函数内部自动组装为一个 dict。
加两个星号**
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
#用该函数时,可以只传入必选参数:
>>> person('Michael', 30)
name: Michael age: 30 other: {}
#也可以传入任意个数的关键字参数:
>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
def person(name, age, **kw):
if 'city' in kw:
# 有 city 参数
pass
if 'job' in kw:
# 有 job 参数
pass
print('name:', name, 'age:', age, 'other:', kw)
命名关键字参数
命名关键字参数需要一个特殊分隔符, 后面的参数被视为命名关键字参数。
def person(name, age, *, city, job):
print(name, age, city, job)
#调用方式如下:
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
#如果没有传入参数名,调用将报错:
>>> person('Jack', 24, 'Beijing', 'Engineer')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: person() takes 2 positional arguments but 4 were given
4、参数组合
在 Python 中定义函数,可以用必选参数、默认参数、可变参数、关键
字参数和命名关键字参数,这 5 种参数都可以组合使用,除了可变参数
无法和命名关键字参数混合。
但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数/命名关键字参数、关键字参数。
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
· 高级特性:切片
可以进行切片操作的变量类型有:str(字符串),tuple(不可变列表),list(可变列表)
#索引0开始,到3截止(不包括3):L[0]、L[1]、L[2]
L[0:3]
#索引1开始,到3截止(不包括3):L[1]、L[2]
L[1:3]
#前3个,若第一个是0,可以省略:L[0]、L[1]、L[2]
L[:3]
#倒数2个:L[-1]、L[-2](倒数第一个元素的索引是-1)
L[-2:]
#倒数第2个开始,倒数第1个截止(不包括):L[-2]
L[-2:-1]
#每隔2个取一个:L[0]、L[2]、L[4]、L[6]、L[8]
L[:10:2]
#所有数:L[0]~L[-1]
L[:]
#所有数,每隔5个取一个
L[::5]
· 高级特性:迭代(Iteration)
list、tuple、str
for element in l:
print(element)
dict
for key in d:
print(key)
for value in d.values():
print(value)
for k,v in d.items()
print(v)
print(k)
判断某个类型是否可以迭代
isinstance('abc', Iterable)
· 高级特性:列表生成式
要生成的元素 x * x 放到前面,后面跟 for 循环,就可以把 list 创建出来。
list1 = [x*x for x in range(1,11)]
>>>list1
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
for 循环后面还可以加上 if 判断:
list2 = [x*x for x in range(1,11) if x%2 == 0]
>>>list2
[4, 16, 36, 64, 100]
还可以使用两层循环
list3 = [m+n for m in 'ABC' for n in 'XYZ']
>>>lsit3
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
· 生成器
在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的 list,从而节省大量的空间。在 Python 中,这种一边循环一边计算的机制,称为生成器: generator。
创建generator的方法:
- 1、把一个列表生成式的[]改成()
g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
- 2、如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个 generator。
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>
定义类
#!/usr/bin/env python
#coding:utf8
# 定义
class Hotel(object):
"""docstring for Hotel"""
def __init__(self, room, cf=1.0, br=15):
self.room = room
self.cf = cf
self.br = br
def cacl_all(self, days=1):
return (self.room * self.cf + self.br) * days
# 使用
if __name__ == '__main__':
stdroom = Hotel(200)
big_room = Hotel(230, 0.9)
print stdroom.cacl_all()
print stdroom.cacl_all(2)
print big_room.cacl_all()
print big_room.cacl_all(3)
- 类内部的函数互相调用,要加上类名。
- init实在构建实例的时候可以传参,也可以自己调用__init函数。
- 所有函数的参数,第一个是self。