string[2] 截取第二个字符
string[-1] 截取倒数第一个字符
string[6:] 截取从第7个字符到结尾
string[:-3] 截取倒数第三个字符前的字符
string[::-1] 创建一个与字符串顺序完全相反的字符串
格式化字符串时,Python使用一个字符串作为模板。模板中有格式符,这些格式符为真实值预留位置,并说明真实数值应该呈现的格式。Python用一个tuple将多个值传递给模板,每个值对应一个格式符。
print("I'm %(name)s. I'm %(age)d year old" % {'name':'Vamei', 'age':99})
格式符可以包含有一个类型码,用以控制显示的类型,如下:
%s 字符串 (采用str()的显示)
%r 字符串 (采用repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为e)
%E 指数 (基底写为E)
%f 浮点数
%F 浮点数,与上相同
%g 指数(e)或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)
%% 字符”%”
%[(name)][flags][width].[precision]typecode
(name)为命名
flags可以有+,-,’ ‘或0。+表示右对齐。-表示左对齐。’ ‘为一个空格,表示在正数的左侧填充一个空格,从而与负数对齐。0表示使用0填充。
width表示显示宽度
precision表示小数点后精度
width, precision为两个整数。我们可以利用*,来动态代入这两个量。
print("%.*f" % (4, 1.2))
Python实际上用4来替换*。所以实际的模板为”%.4f”。
tt=’555’
ts=string.atoi(tt)
ts即为tt转换成的数字
转换为浮点数 string.atof(tt)
int(tt)即可。
tt=322
tem=’%d’ %tt
tem即为tt转换成的字符串
isinstance([], Iterable) 判断一个元素是否能使用for元素迭代
Python的元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号,列表使用方括号。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4, 5, 6, 7 );
print "tup1[0]: ", tup1[0]
print "tup2[1:5]: ", tup2[1:5]
list是一种有序的集合,可以随时添加和删除其中的元素。可以通过索引访问list的元素.索引可以是负数,表示从后往前的顺序读取。List中的元素可以是不同类型。
classmates = [‘Michael’, ‘Bob’, ‘Tracy’]
classmates.append(‘Adam’)
classmates.insert(1,’Jack’)
classmates.pop(i)
classmates[1] = ‘Sarah’
len(classmates)
d = {‘Michael’: 95, ‘Bob’: 75, ‘Tracy’: 85}
‘Thomas’ in d
d.get(‘Thomas’) 如果不存在会返回None
d.get(‘Thomas’, -1) 不存在返回-1
d.pop(‘Bob’)
与list相似,但是元素不能重复. 如果创建时传入重复元素,会被set过滤掉.
s = set([1, 2, 3])
s.add(4)
s.remove(4)
if x in s
if x not in s
可以不按顺序调用,但是必须输入参数名
printinfo( age=50, name="miki" );
可以使用默认参数,调用的时候可以不传递
def printinfo( name, age = 35 ):
printinfo("william")
class Student(object):
pass
类名首字母通常大写,
s=Student()
s.name=”bart”
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def get_grade(self):
if self.score >= 90:
return 'A'
elif self.score >= 60:
return 'B'
else:
return 'C'
第一个参数必须是self
以两个下划线__开头的变量为私有变量,外部不可以访问。
可用通过增加方法的形式,访问私有变量。
def get_name(self):
return self.__name
python本身不对私有变量强制限制访问,私有变量只是被设置为了别名
当子类方法的名称与父类相同时,方法被覆写
isinstance(变量,类型) 返回true表示是该类型或继承自该类型
type函数可用显示对象的类型
dir() 显示对象的所有属性和方法
getattr() 获取属性
setattr() 设置属性
hasattr() 是否含有属性
切片用于截取集合中的元素。
L[2:4]
通过for … in来迭代元素
for ch in ‘ABC’:
print(ch)
list(range(1, 11))
>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list(range(1,11,2)) #从1到11,间隔为2
list(range(5)) #从0到5,不包含5
[x * x for x in range(1, 11)]
[x * x for x in range(1, 11) if x % 2 == 0]
[m + n for m in 'ABC' for n in 'XYZ']
[d for d in os.listdir('.')] os.listdir可以列出文件和目录
与列表生成器相比,在循环的过程中才会生成元素,对于大量的数据,避免过早生成数据
定义生成器,list使用中括号,generator使用小括号
g = (x * x for x in range(10))
next(g) 获取下一个元素
函数可以作为参数被传递
def add(x, y, f):
return f(x) + f(y)
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
def abc(a, b, c):
return a*10000 + b*100 + c
list1 = [11,22,33]
list2 = [44,55,66]
list3 = [77,88,99]
map(abc,list1,list2,list3)
[114477, 225588, 336699]
把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算
把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
它还可以接收一个key函数来实现自定义的排序
sorted([‘bob’, ‘about’, ‘Zoo’, ‘Credit’], key=str.lower)
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
lambda x: x * x
相当于
def f(x):
return x * x
偏函数把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数。
int2 = functools.partial(int, base=2)
相当于
kw = { 'base': 2 }
int('10010', **kw)
设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')
logging可以打印出异常日志,并可配置,输出到文件等
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
通过继承内置的异常(ValueError,TypeError等)自定义异常
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')
如果断言失败,assert语句本身就会抛出AssertionError
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
启动Python解释器时可以用-O参数来关闭assert
有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。
同时,一条语句可以同时输出到不同的地方,比如console和文件。
import logging
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)
启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。
$ python3 -m pdb err.py
python中处理正则表达式的是re模块
match(pattern,string,flags=0) 尝试用正则表达式模式pattern匹配字符串string,如果匹配成功,则返回一个匹配对象;否则返回None。
search(pattern,string,flags=0) 在字符串string中查找正则表达式模式pattern的第一次出现,如果匹配成功,则返回一个匹配对象,否则返回None
findall(pattern,string[,flags])* 在字符串string中查找正则表达式模式pattern的所有(非重复)出现;返回一个匹配对象的列表
split(pattern,string,max=0) 根据正则表达式pattern中的分隔符把字符string分割为一个列表,最多分割max次
sub(pattern,rep1,string,max=0) 把字符串string中所有匹配正则表达式pattern的地方替换成字符串rep1。
python的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块
Python的threading模块有个current_thread()函数,它永远返回当前线程的实例。
def loop():
print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)
balance = 0
lock = threading.Lock()
def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要释放锁:
lock.release()
Python的线程虽然是真正的线程,解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。
不过,也不用过于担心,Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。
import threading
local_school = threading.local()
def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。
sleep(1) 当前线程等待1秒.time模块中的sleep方法.
执行INSERT等操作后要调用commit()提交事务;
MySQL的SQL占位符是%s。
$ pip install mysql-connector-python --allow-external mysql-connector-python
或
$ pip install mysql-connector
import mysql.connector
conn = mysql.connector.connect(user='root', password='password', database='test')
cursor = conn.cursor()
cursor.execute('select * from user where id = %s', ('1',))
values = cursor.fetchall()
values
[('1', 'Michael')]
fetchall()方法返回的是一个list
# 导入socket库:
import socket
# 创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('www.sina.com.cn', 80))
# 发送数据:
s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
buffer = []
while True:
# 每次最多接收1k字节:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break
data = b''.join(buffer)
# 关闭连接:
s.close()
header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))
print(html)
# 导入socket库:
import socket
import threading
import time
# 创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口:
s.bind(('127.0.0.1', 9999))
#等待连接的最大数是5
s.listen(5)
print('Waiting for connection...')
while True:
# 接受一个新连接:
sock, addr = s.accept()
# 创建新线程来处理TCP连接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
def tcplink(sock, addr):
print('Accept new connection from %s:%s...' % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024)
#当前线程休眠一秒
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
httplib实现了HTTP和HTTPS的客户端协议,一般不直接使用,在python更高层的封装模块中(urllib,urllib2)使用了它的http实现。
conn1 = HTTPConnection('www.baidu.com:80')
urllib 和urllib2都是接受URL请求的相关模块,但是urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL。
这意味着,你不可以伪装你的User Agent字符串等。
urllib提供urlencode方法用来GET查询字符串的产生,而urllib2没有。这是为何urllib常和urllib2一起使用的原因。
目前的大部分http请求都是通过urllib2来访问的
google = urllib.urlopen('http://www.google.com')
print 'http header:/n', google.info()
print 'http status:', google.getcode()
print 'url:', google.geturl()
for line in google: # 就像在操作本地文件
print line,
google.close()
urlretrieve方法直接将远程数据下载到本地。参数filename指定了保存到本地的路径(如果未指定该参数,urllib会生成一个临时文件来保存数据);参数reporthook是一个回调函数,当连接上服务器、以及相应的数据块传输完毕的时候会触发该回调。
官方文档
http://docs.python-requests.org/en/master/api/
import requests
r = requests.get('http://cuiqingcai.com')
print type(r)
print r.status_code
print r.encoding
#print r.text 打印页面内容
print r.cookies
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)
print r.url
http://httpbin.org/get?key2=value2&key1=value1
r = requests.get('https://github.com/timeline.json', stream=True)
r.raw
r.raw.read(10)
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
payload = {'key1': 'value1', 'key2': 'value2'}
headers = {'content-type': 'application/json'}
r = requests.get("http://httpbin.org/get", params=payload, headers=headers)
r = requests.post("http://httpbin.org/post")
r = requests.put("http://httpbin.org/put")
r = requests.delete("http://httpbin.org/delete")
r = requests.head("http://httpbin.org/get")
r = requests.options("http://httpbin.org/get")
requests.get('http://github.com', timeout=0.001)
functools,用于高阶函数:指那些作用于函数或者返回其它函数的函数,通常只要是可以被当做函数调用的对象就是这个模块的目标。
在Python 2.7 中具备如下方法,
cmp_to_key,将一个比较函数转换关键字函数;
partial,针对函数起作用,并且是部分的;
reduce,与python内置的reduce函数功能一样;
total_ordering,在类装饰器中按照缺失顺序,填充方法;
update_wrapper,更新一个包裹(wrapper)函数,使其看起来更像被包裹(wrapped)的函数;
wraps,可用作一个装饰器,简化调用update_wrapper的过程;
单行注释使用#表示
多行注释使用连续三个单引号或者双引号
导入模块
import module
导入模块的函数方法
from module import name
文件名即是模块名。
可以通过包来组织模块。包可以有多个层级
每一个包目录下面都会有一个init.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。init.py可以是空文件,也可以有Python代码,因为init.py本身就是一个模块,而它的模块名就是包名