Python3学习笔记 本篇为学习廖老师的Python3教程 所做的摘要笔记。有一些自己写归纳的东西,一直在完善中。
安装篇
mac上自带的python是2.x的,先装上3.x再说。
brew install python3
brew link python
* 此时再去link一下
基础语法 字符串 1 2 3 4 5 chr(66)输出66的字符形式 ord与上面相反 格式化 >>> "%s,%s" % ('aaa','bbb') 'aaa,bbb'
list,tuple list 声明一个数组:list = [‘xxxx’, True, 123] append,insert,pop可以操作数组。可以使用list[-1] 取出list中最后一个。以此类推
tuple 不可变的list:tuple = (‘xxx’, 123)注意 当只有一个元素的tuple时,使用逗号消除歧义。应这样声明tuple = (‘xxx’, )
条件判断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 第一种: if <条件判断>: ... else: ... 第二种: if <条件判断1>: <执行1> elif <条件判断2>: <执行2> elif <条件判断3>: <执行3> else: <执行4>
字符串不能和int型比较,需要用int()函数转换
循环 for…in… 和while
1 2 3 4 5 6 7 8 9 10 11 12 # for...in.. names = ['Michael', 'Bob', 'Tracy'] for name in names: print(name) # while sum = 0 n = 99 while n > 0: sum = sum + n n = n - 2 print(sum)
dict和set 1 2 3 4 5 6 7 8 # dict(其实就是map,键值对) d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} d['Tracy'] = 67 # 使用'Thomas' in d判断是否存在key # set定义 s = set([1, 2, 3])
函数 官方文档
使用help(函数名) 查询函数用法
定义 1 2 3 4 abstest.py def test(x): return xxx;
使用from abstest import my_abs引入函数调用
关键字pass 什么也不做
检查类型
1 2 3 4 5 6 7 def test(x): if not isinstance(x, (int, float)): raise TypeError('bad operand type') if x >= 0: return x else: return -x
返回多个值
1 2 3 4 5 6 7 def test(x): return x1,x2 >>> value = test(2) 这个value是一个tuple。 也可以这么写: >>> x1,x2 = test(2)
参数默认值
可变参
1 2 3 4 5 6 7 def calc(*test): 相当于java中的... 调用时如果参数是个list,可以直接使用*展开 calc(*list)
关键字参数
1 2 3 4 5 def test(test1, test2, **kw) kw接受一个dict键值对 比如 test(x,x,key=value, key=value)
关键字参数命名检查
1 2 3 4 5 6 7 8 9 # 自我检查 def person(name, age, **kw): if 'city' in kw: # 有city参数 pass if 'job' in kw: # 有job参数 pass print('name:', name, 'age:', age, 'other:', kw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下: def person(name, age, *, city, job): print(name, age, city, job) 使用*隔开。 如果中间有一个可变参,就不要写额外的*了 例如 def person(name, age, *args, city, job): print(name, age, city, job) 调用时一定要写参数名, # 调用 person('Jack', 24, city='Beijing', job='Engineer')
参数组合
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
1 2 def f1(a, b, c=0, *args, **kw): print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
切面取值
有一个list值为[0, 1, 2, 3, …, 99] 取出前10个list[0:10],0如果是第一个,可以省略 前10个数,每3个取一个,list[0:10:3], list[:] 原样copy出一个数组
迭代
默认情况下,dict迭代的是key,for key in d:。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。 可以使用isinstance(‘abc’, Iterable)判断该对象能不能迭代。
迭代中的下标
1 2 3 4 5 6 >>> for i, value in enumerate(['A', 'B', 'C']): ... print(i, value) ... 0 A 1 B 2 C
上面的for循环里,同时引用了两个变量,在Python里是很常见的,比如下面的代码:
1 2 3 4 5 6 >>> for x, y in [(1, 1), (2, 4), (3, 9)]: ... print(x, y) ... 1 1 2 4 3 9
列表生成器
1 2 3 4 5 [x * x for x in range(1, 11) if x % 2 == 0] x * x 是结果。中间for...in是迭代。后面的if x % 2 == 0是条件。相当于java的list.filter((x) => x %2 == 0).map((x) => x * x); [m + n for m in 'ABC' for n in 'XYZ'] 多维度组合,这个还是比较有用的,使用了两个迭代生成的新的list
上面的列表生成器直接生成一个list对象。使用()可以产生一个generator,动态的计算下一个元素,而不是全部塞在内存里。
1 2 3 g = (x * x for x in range(10)) next(g) //使用next读取元素 for n in g: //使用迭代读取元素
一个函数中出现yield关键字,那么这个函数的返回值是一个generator,每一次的next都执行到yield返回的地方。只到抛出异常。for…in方式不抛出异常。所以读不到最后的return的值
迭代器
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
Python的for循环本质上就是通过不断调用next()函数实现的
1 2 isinstance([], Iterable) 判断是不是Iterable isinstance([], Iterator) 判断是不是Iterator
函数式编程 map,reduce,filter,sorted 闭包 返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
匿名函数 lambda x: x * x,冒号前面的x是参数,后面是表达式。
装饰器 函数也是一个对象,所以,函数也有自己的属性,例如name 就是函数名 如果想动态更改一个函数的行为,可以使用装饰器语法。 装饰器本质上是一个高阶函数,它接收目标函数,然后做一些事情后,再返回目标函数的引用。
1 2 3 4 5 def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper
这个例子,log函数接收一个函数参数func。返回一个函数引用wrapper,在wrapper内先打印了func名字,后执行了func。 如果我们执行目标函数的地方都改为log(目标函数),那么执行目标函数前都会打印目标函数的名字。 python为我们提供了语法支持
1 2 3 @log def now(): print('2015-3-25')
相当于
下面是一个完整的例子,带参数,带copy函数属性
1 2 3 4 5 6 7 8 9 10 import functools def log(text): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator
1 2 3 4 5 6 >>> import functools >>> int2 = functools.partial(int, base=2) >>> int2('1000000') 64 >>> int2('1010101') 85
functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
重构时会非常有用。
使用模块 非常简单 import
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ' a test module ' __author__ = 'kahn' import sys def test(): args = sys.argv if len(args)==1: print('Hello,World!') elif len(args)==2: print('Hello, %s!' % args[1]) else: print('Too many arguments!') if __name__=='__main__': test()
安装第三方库 官方插件库
先查找好库名,然后使用pip install xxx 安装
综合插件库anaconda
面向对象编程 语法 class Test(object): 后面括号为继承自哪个类
声明变量 test = Test()
可以给对象附加属性,例如,test.param1 = ‘testxxx’
定义类的初始变量 1 2 3 4 5 class Test(object): def __init__(self, param1, param2): self.param1 = param1 self.param1 = param2
生成对象时,第一个参数self忽略。
定义类的方法 1 2 3 4 5 6 7 8 class Test(object): def __init__(self, param1, param2): self.param1 = param1 self.param1 = param2 def testMethod(self): print(self.param1);
注意:定义类的方法,第一次参数一定要是self,self为当前对象的实例,调用时无需传入
定义私有变量 1 2 3 4 5 class Test(object): def __init__(self, param1, param2): self.__param1 = param1 self.__param1 = param2
在成员变量前加两个下划线就是私有成员变量,外部不可访问
继承,多态 class Test(object)就是继承了。
在子类中可以覆盖父类的方法。
和java不同的一点。如果一个方法接收一个对象,它只使用了这个对象的test方法。那么,传入对象的类型可以是不固定的,只要有test方法就可以了。
isinstance(b, Test) 判断对象类型
对象的信息 type方法
1 2 3 4 5 6 7 8 9 10 11 12 获取对象信息 >>> type(123) <class 'int'> 做比较 >>> import types >>> type(123)==type(456) True >>> type(123)==int True >>> type(fn)==types.FunctionType True
isinstances方法
1 2 3 类型还可以传多个 >>> isinstance([1, 2, 3], (list, tuple)) True
dir()方法,获取对象的属性及方法,此外还有getattr()、setattr()以及hasattr(),都是进行属性方法操作的。
类属性 1 2 class Test(object): name = 'Test'
在类外给类附加方法 附加在对象上的方法,只本对象有效
1 2 3 4 5 6 7 8 >>> def set_age(self, age): # 定义一个函数作为实例方法 ... self.age = age ... >>> from types import MethodType >>> s.set_age = MethodType(set_age, s) # 给实例绑定一个方法 >>> s.set_age(25) # 调用实例方法 >>> s.age # 测试结果 25
附加类方法
1 2 3 4 >>> def set_score(self, score): ... self.score = score ... >>> Student.set_score = set_score
限制附加属性
1 2 class Student(object): __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
使用@property使外部可以方便访问变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Person(object): def __init__(self, name, height): self.__name = name self.__height = height @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name @property def height(self): return self.__height def test(): person = Person("kahn", 180) print(person.name) print(person.height) person.name = 'xxx' print(person.name) if __name__=='__main__': test()
多继承 1 class Dog(Mammal, Runnable):
类的特殊字段方法 __slots__
限制__str__
相当于toString __repr__
开发者模式的toString。 可以这样__repr__ = __str__
_iter__和__next__
,第一个返回一个迭代对象,使用迭代对象会调用该对象的__next__
__getitem__
像数组一样获取数据__getattr__
如果找不到属性,该方法将会触发__call__
把对象变为直接可调用 callable()来判断该对象是不是可调用的
枚举 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from enum import Enum Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) //这样我们就获得了Month类型的枚举类,可以直接使用Month.Jan来引用一个常量,或者枚举它的所有成员: //遍历 for name, member in Month.__members__.items(): print(name, '=>', member, ',', member.value) //扩展,自定义value。(默认枚举的值为从1开始赋值) //@unique装饰器可以帮助我们检查保证没有重复值。 from enum import Enum, unique @unique class Weekday(Enum): Sun = 0 # Sun的value被设定为0 Mon = 1 Tue = 2 Wed = 3 Thu = 4 Fri = 5 Sat = 6
元类 使用type的方式动态创建类
1 2 3 4 >>> def fn(self, name='world'): # 先定义函数 ... print('Hello, %s.' % name) ... >>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class
metaclass
相当于使用代码动态构建类,具体还请看这边
错误、调试和测试 异常 python的try catch语法
1 2 3 4 5 6 7 8 9 10 11 12 13 try: print('try...') r = 10 / int('2') print('result:', r) except ValueError as e: print('ValueError:', e) except ZeroDivisionError as e: print('ZeroDivisionError:', e) else: print('no error!') finally: print('finally...') print('END')
Python所有的错误都是从BaseException类派生的 常见异常类
记录异常
使用 import logging logging.exception(e)
抛出异常
使用raise FooError('invalid value: %s' % s)
调试 断言语法
assert n != 0, 'n is zero!'
启动Python解释器时可以用-O参数来关闭assert
logging
import logging logging.basicConfig(level=logging.INFO) s = ‘0’ n = int(s) logging.info(‘n = %d’ % n) print(10 / n)
pdb 调试器
启动调试器python -m pdb err.py
单元测试 单测写法
测试方法必须以test开头
1 2 3 4 5 6 7 8 9 10 11 12 //引入单测 import unittest //引入要测试的类 from mydict import Dict class TestDict(unittest.TestCase): def test_init(self): d = Dict(a=1, b='test') self.assertEqual(d.a, 1) self.assertEqual(d.b, 'test') self.assertTrue(isinstance(d, dict))
执行命令
$ python -m unittest mydict_test
setUp与tearDown
和java一样,同样有这两个方法
写法
1 2 3 4 5 6 7 class TestDict(unittest.TestCase): def setUp(self): print('setUp...') def tearDown(self): print('tearDown...')
文档测试 在文档中也可按固定格式写出测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def abs(n): ''' Function to get absolute value of number. Example: >>> abs(1) 1 >>> abs(-1) 1 >>> abs(0) 0 ''' return n if n >= 0 else (-n)
IO 文件读写 打开文件
第二个参数是模式,r表示读一个文本,rb表示读一个二进制
1 >>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
关闭流
第一种,try finally
1 2 3 4 5 6 7 try: f = open('/path/to/file', 'r') print(f.read()) finally: if f: f.close()
第二种 with语法
1 2 3 with open('/path/to/file', 'r') as f: print(f.read())
读
read() 读取全部 read(size) 读取固定字节 readlines() 读取一行
写
write() 默认‘w’是覆盖,‘a’追加
StringIO和BytesIO StringIO 在内存中读写字符串
1 2 3 4 5 6 7 8 9 10 >>> from io import StringIO >>> f = StringIO() >>> f.write('hello') 5 >>> f.write(' ') 1 >>> f.write('world!') 6 >>> print(f.getvalue()) hello world!
BytesIO 在内存中读写byte字节
1 2 3 4 5 6 >>> from io import BytesIO >>> f = BytesIO() >>> f.write('中文'.encode('utf-8')) 6 >>> print(f.getvalue()) b'\xe4\xb8\xad\xe6\x96\x87'
OS扩展包(操作文件和目录) 引入OS
1 2 3 >>> import os >>> os.name # 操作系统类型 'posix'
os.environ获取所有环境变量,os.environ.get(‘key’)获取具体某个环境变量
操作文件和目录
基本操作
1 2 3 4 5 6 7 8 9 10 # 查看当前目录的绝对路径: >>> os.path.abspath('.') '/Users/michael' # 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来: >>> os.path.join('/Users/michael', 'testdir') '/Users/michael/testdir' # 然后创建一个目录: >>> os.mkdir('/Users/michael/testdir') # 删掉一个目录: >>> os.rmdir('/Users/michael/testdir')
split
1 2 3 4 5 >>> os.path.split('/Users/michael/testdir/file.txt') ('/Users/michael/testdir', 'file.txt') >>> os.path.splitext('/path/to/file.txt') ('/path/to/file', '.txt')
shutil模块提供了copyfile()的函数,你还可以在shutil模块中找到很多实用函数,它们可以看做是os模块的补充
实例:
1 2 3 4 5 6 7 列出当前目录下的所有目录 >>> [x for x in os.listdir('.') if os.path.isdir(x)] ['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...] 列出所有的.py文件 >>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py'] ['apis.py', 'config.py', 'models.py', 'pymonitor.py', 'test_db.py', 'urls.py', 'wsgiapp.py']
序列化 pickle模块的序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 dumps 用法 >>> import pickle >>> d = dict(name='Bob', age=20, score=88) >>> pickle.dumps(d) dump用法 >>> f = open('dump.txt', 'wb') >>> pickle.dump(d, f) >>> f.close() 反序列化 >>> f = open('dump.txt', 'rb') >>> d = pickle.load(f) >>> f.close() >>> d {'age': 20, 'score': 88, 'name': 'Bob'}
json模块的序列化
1 2 3 4 5 6 7 8 9 10 序列化 >>> import json >>> d = dict(name='Bob', age=20, score=88) >>> json.dumps(d) '{"age": 20, "score": 88, "name": "Bob"}' 反序列化 >>> json_str = '{"age": 20, "score": 88, "name": "Bob"}' >>> json.loads(json_str) {'age': 20, 'score': 88, 'name': 'Bob'}
定制json序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def student2dict(std): return { 'name': std.name, 'age': std.age, 'score': std.score } >>> print(json.dumps(s, default=student2dict)) {"age": 20, "name": "Bob", "score": 88} def dict2student(d): return Student(d['name'], d['age'], d['score']) >>> json_str = '{"age": 20, "score": 88, "name": "Bob"}' >>> print(json.loads(json_str, object_hook=dict2student)) <__main__.Student object at 0x10cd3c190>
进程和线程 进程 os.fork() 创建一个子进程,该方法在父进程和子进程中都会返回值
multiprocessing模块Process类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from multiprocessing import Process import os # 子进程要执行的代码 def run_proc(name): print('Run child process %s (%s)...' % (name, os.getpid())) if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Process(target=run_proc, args=('test',)) print('Child process will start.') p.start() p.join() print('Child process end.')
multiprocessing模块Pool类 进程池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from multiprocessing import Pool import os, time, random def long_time_task(name): print('Run task %s (%s)...' % (name, os.getpid())) start = time.time() time.sleep(random.random() * 3) end = time.time() print('Task %s runs %0.2f seconds.' % (name, (end - start))) if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Pool(4) for i in range(5): p.apply_async(long_time_task, args=(i,)) print('Waiting for all subprocesses done...') p.close() p.join() print('All subprocesses done.')
对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了
subprocess模块
1 2 3 4 5 6 import subprocess print('$ nslookup www.python.org') r = subprocess.call(['nslookup', 'www.python.org']) print('Exit code:', r)
进程间通信
Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from multiprocessing import Process, Queue import os, time, random # 写数据进程执行的代码: def write(q): print('Process to write: %s' % os.getpid()) for value in ['A', 'B', 'C']: print('Put %s to queue...' % value) q.put(value) time.sleep(random.random()) # 读数据进程执行的代码: def read(q): print('Process to read: %s' % os.getpid()) while True: value = q.get(True) print('Get %s from queue.' % value) if __name__=='__main__': # 父进程创建Queue,并传给各个子进程: q = Queue() pw = Process(target=write, args=(q,)) pr = Process(target=read, args=(q,)) # 启动子进程pw,写入: pw.start() # 启动子进程pr,读取: pr.start() # 等待pw结束: pw.join() # pr进程里是死循环,无法等待其结束,只能强行终止: pr.terminate()
线程 ython的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块,对_thread进行了封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import time, threading # 新线程执行的代码: def loop(): print('thread %s is running...' % threading.current_thread().name) n = 0 while n < 5: n = n + 1 print('thread %s >>> %s' % (threading.current_thread().name, n)) time.sleep(1) print('thread %s ended.' % threading.current_thread().name) 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)
加锁
1 2 3 4 5 6 7 8 9 10 11 lock = threading.Lock() def run_thread(n): for i in range(100000): # 先要获取锁: lock.acquire() try: # 放心地改吧: change_it(n) finally: # 改完了一定要释放锁: lock.release()
ThreadLocal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import threading # 创建全局ThreadLocal对象: local_school = threading.local() def process_student(): # 获取当前线程关联的student: std = local_school.student print('Hello, %s (in %s)' % (std, threading.current_thread().name)) def process_thread(name): # 绑定ThreadLocal的student: local_school.student = name process_student() t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A') t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
分布式进程 1 2 import random, time, queue from multiprocessing.managers import BaseManager
具体看教程
正则表达式 re模块中含有正则表达式所有的方法
1 2 3 s = 'ABC\\-001' # Python的字符串 s = r'ABC\-001' # Python的字符串 前面+r可以省去转译\
match()方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None。常见的判断方法就是:
1 2 3 4 5 test = '用户输入的字符串' if re.match(r'正则表达式', test): print('ok') else: print('failed')
编译正则,以便重复使用
1 2 3 4 5 6 7 8 >>> import re # 编译: >>> re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$') # 使用: >>> re_telephone.match('010-12345').groups() ('010', '12345') >>> re_telephone.match('010-8086').groups() ('010', '8086')
常用内置api datetime
1 from datetime import datetime
collections
1 2 3 4 5 namedtuple deque defaultdict OrderedDict Counter
struct
用来处理基本数据类型和byte之间的转换
1 2 >>> import struct >>> struct.pack('>I', 10240099)
hashlib
一些hash算法
contextlib
对with语法的解析
urllib
提供一些访问url的方法
get
1 2 3 4 5 6 7 8 9 from urllib import request req = request.Request('http://www.douban.com/') req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25') with request.urlopen(req) as f: print('Status:', f.status, f.reason) for k, v in f.getheaders(): print('%s: %s' % (k, v)) print('Data:', f.read().decode('utf-8'))
post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from urllib import request, parse print('Login to weibo.cn...') email = input('Email: ') passwd = input('Password: ') login_data = parse.urlencode([ ('username', email), ('password', passwd), ('entry', 'mweibo'), ('client_id', ''), ('savestate', '1'), ('ec', ''), ('pagerefer', 'https://passport.weibo.cn/signin/welcome?entry=mweibo&r=http%3A%2F%2Fm.weibo.cn%2F') ]) req = request.Request('https://passport.weibo.cn/sso/login') req.add_header('Origin', 'https://passport.weibo.cn') req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25') req.add_header('Referer', 'https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=http%3A%2F%2Fm.weibo.cn%2F') with request.urlopen(req, data=login_data.encode('utf-8')) as f: print('Status:', f.status, f.reason) for k, v in f.getheaders(): print('%s: %s' % (k, v)) print('Data:', f.read().decode('utf-8'))
Web开发 1 2 3 4 5 6 7 8 9 10 11 12 13 #application.py def application(environ, start_response): start_response('200 ok', [('Content-Type', 'text/html')]) return [b'<h1>hello web</h1>'] #server.py from wsgiref.simple_server import make_server from web.application import application httpd = make_server('', 8080, application) print('Server Http on port 8080...') httpd.serve_forever()
异步io 1 2 3 4 5 6 7 8 9 10 11 12 13 import threading import asyncio @asyncio.coroutine def hello(): print('Hello world! (%s)' % threading.currentThread()) yield from asyncio.sleep(1) print('Hello again! (%s)' % threading.currentThread()) loop = asyncio.get_event_loop() tasks = [hello(), hello()] loop.run_until_complete(asyncio.wait(tasks)) loop.close()
新老用法
1 2 3 4 5 6 7 8 9 10 11 12 @asyncio.coroutine def hello(): print("Hello world!") r = yield from asyncio.sleep(1) print("Hello again!") async def hello(): print("Hello world!") r = await asyncio.sleep(1) print("Hello again!")
注意新语法只能用在Python 3.5以及后续版本