Python基础语法

最近在学Python,主要代码整理自廖雪峰博客:html

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000git

 

基础

print 'I\'m \"OK\"!'

a = 123  # a是整数
print a
a = 'ABC'  # a变为字符串
print a

a = 100
if a >= 0:  # 注意冒号
    print a
else:
    print -a
# int转成string,函数int(string)
# string转成int,函数str(number)
print len(u'ABC')
print 'Hi, %s, you have $%d.' % ('Michael', 1000000)
print 'Age: %s. Gender: %s' % (25, True)

classmates = ['Michael', 'Bob', 'Tracy']
classmates.append('Adam')
classmates.insert(1, 'Jack')
classmates.pop()
classmates.pop(1)
classmates[1] = 123  # 类型能够不一样
# 相等的
print classmates
print classmates[len(classmates) - 1] == classmates[-1]
print classmates[len(classmates) - 2] == classmates[-2]

# tuple和list很是相似,可是tuple一旦初始化就不能修改,没有append(),insert()这样的方法
# 能够正常地使用classmates[-1],但不能赋值成另外的元素
t = ('Michael', 'Bob', 'Tracy')
t = (1,);  # 只有1个元素的tuple定义时必须加一个逗号,,来消除歧义
t = (1, 2)
print t

# 若是在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的elif和else
# 下面打印  teenager
age = 20
if age >= 6:
    print 'teenager'
elif age >= 18:
    print 'adult'
else:
    print 'kid'

sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    sum = sum + x
print sum
sum = 0
for x in range(101):
    sum = sum + x
print sum

sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print sum

# 打印
# name = raw_input('please enter your name: ')
# print 'hello,', name

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print d['Michael']
d['Adam'] = 67
print d['Adam']
# 要避免key不存在的错误
print 'Thomas' in d
print d.get('Thomas')
print d.get('Thomas', -1)
d.pop('Bob')
key = [1, 2, 3]
# key的对象就不能变,而list是可变的,就不能做为key
# d[key] = 'a list'
print d
# 要建立一个set,须要提供一个list做为输入集合
s1 = set([1, 2, 3])
# 重复元素在set中自动被过滤
s1 = set([1, 1, 2, 2, 3, 3])
s1.add(4)
s1.remove(4)
s2 = set([2, 3, 4])
# 交集、并集
print s1 & s2, s1 | s2

# 对于可变对象,好比list,对list进行操做,list内部的内容是会变化的
a = ['c', 'b', 'a']
a.sort()
print a
# 对于不变对象来讲,调用对象自身的任意方法,也不会改变该对象自身的内容。
# 相反,这些方法会建立新的对象并返回,这样,就保证了不可变对象自己永远是不可变的。
a = 'abc'
b = a.replace('a', 'A')
print a, b

  

函数

# 函数
# 比较函数
print cmp(1, 2)
# 数据类型转换
print int('123')
print int(12.34)
str(1.23)
unicode(100)
bool(1)
bool('')


# 定义函数,若是没有return语句,函数执行完毕后也会返回结果,只是结果为None。
# return None能够简写为return,函数执行完毕没有return语句时,自动return None。
# 只容许整数和浮点数类型的参数。数据类型检查能够用内置函数isinstance实现
def my_abs(x):
    if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x


a = my_abs  # 变量a指向abs函数
print a(-1)  # 因此也能够经过a调用abs函数


# 空函数
# 若是想定义一个什么事也不作的空函数,能够用pass语句
# pass能够用来做为占位符,好比如今还没想好怎么写函数的代码,就能够先放一个pass,让代码能运行起来
# 缺乏了pass,代码运行就会有语法错误。
def nop():
    pass


# 能够返回多个值,实际是返回tuple,这样写起来方便
def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny


x, y = move(100, 100, 60, math.pi / 6)
print x, y
r = move(100, 100, 60, math.pi / 6)
print r


# 默认参数,必选参数在前,默认参数在后
# 当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就能够做为默认参数。
def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s


print power(5), power(5, 3)


def enroll(name, gender, age=6, city='Beijing'):
    print 'name:', name
    print 'gender:', gender
    print 'age:', age
    print 'city:', city


print  enroll('Sarah', 'F')
print enroll('Bob', 'M', 7)
# 当不按顺序提供部分默认参数时,须要把参数名写上
print enroll('Adam', 'M', city='Tianjin')


def add_end(L=[]):
    L.append('END')
    return L


print add_end()
print add_end()  # ['END', 'END'],不对


# 默认参数必须指向不变对象!,修改上面的例子,不然运行会有逻辑错误!
def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L


# 可变参数,在参数前面加了一个*号
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum


print calc(1, 2)
print calc()

# 若是已经有一个list或者tuple,要调用一个可变参数怎么办?
nums = [1, 2, 3]
print calc(nums[0], nums[1], nums[2])
print calc(*nums)


# 关键字参数,能够扩展函数的功能
# 好比,在person函数里,咱们保证能接收到name和age这两个参数,
# 可是,若是调用者愿意提供更多的参数,咱们也能收到
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'}

kw = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, city=kw['city'], job=kw['job'])
person('Jack', 24, **kw)


# 参数组合
# 在Python中定义函数,能够用必选参数、默认参数、可变参数和关键字参数,这4种参数均可以一块儿使用
# 注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
def func(a, b, c=0, *args, **kw):
    print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw


print func(1, 2)
# a = 1 b = 2 c = 0 args = () kw = {}
print func(1, 2, c=3)
# a = 1 b = 2 c = 3 args = () kw = {}
print func(1, 2, 3, 'a', 'b')
# a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
print func(1, 2, 3, 'a', 'b', x=99)
# a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}

# 要注意定义可变参数和关键字参数的语法:
# *args是可变参数,args接收的是一个tuple;
# **kw是关键字参数,kw接收的是一个dict。
args = (1, 2, 3, 4)  # tuple
kw = {'x': 99}  # dict
print func(*args, **kw)


# a = 1 b = 2 c = 3 args = (4,) kw = {'x': 99}

# 递归
def fact(n):
    if n == 1:
        return 1
    return n * fact(n - 1)


# 尾递归
def fact(n):
    return fact_iter(n, 1)


# 切片
def fact_iter(num, product):
    if num == 1:
        return product
    return fact_iter(num - 1, num * product)


L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
r = []
n = 3
for i in range(n):
    r.append(L[i])

# 迭代
print r
# 切片(Slice)操做符,取前3个元素,用一行代码就能够完成
print L[0:3]
# 若是第一个索引是0,还能够省略
print L[:3]
# 取倒数第一个元素
print L[-2:-1]
# 取后俩个元素
print L[-2:]
# 原样复制一个list:
print L[:]
# tuple也是一种list,惟一区别是tuple不可变。所以,tuple也能够用切片操做,只是操做的结果还是tuple:
print (0, 1, 2, 3, 4, 5)[:3]
print 'ABCDEFG'[:3]

# 只要是可迭代对象,不管有无下标,均可以迭代,好比dict就能够迭代
# 遍历key
d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
    print key
# 遍历value
for value in d.itervalues():
    print value
# 遍历key,value
for k, v in d.iteritems():
    print k, '=', v

for ch in 'ABC':
    print ch

from collections import Iterable

print isinstance([1, 2, 3], Iterable)  # list是否可迭代
print isinstance('abc', Iterable)  # str是否可迭代
print isinstance(123, Iterable)  # 整数是否可迭代,false
print isinstance(x, str)  # 判断一个变量是否是字符串

# 这样就能够在for循环中同时迭代索引和元素自己
for i, value in enumerate(['A', 'B', 'C']):
    print i, value

for x, y in [(1, 1), (2, 4), (3, 9)]:
    print x, y

# 列表生成式
print range(1, 11)
L = []
# [1x1, 2x2, 3x3, ..., 10x10]
for x in range(1, 11):
    L.append(x * x)
print [x * x for x in range(1, 11)]
# 筛选出仅偶数的平方
print [x * x for x in range(1, 11) if x % 2 == 0]
# 两层循环,能够生成全排列
print [m + n for m in 'ABC' for n in 'XYZ']
# 列出当前目录下的全部文件和目录名
print [d for d in os.listdir('.')]  # os.listdir能够列出文件和目录
L = ['Hello', 'World', 'IBM', 'Apple']
# 一个list中全部的字符串变成小写
print [s.lower() for s in L]

# 生成器:若是列表元素能够按照某种算法推算出来,这样就没必要建立完整的list,从而节省大量的空间
# 和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator
L = [x * x for x in range(10)]
g = (x * x for x in range(10))
print g.next()
for n in g:
    print n


# 若是一个函数定义中包含yield关键字,那么这个函数就再也不是一个普通函数,而是一个generator
def odd():
    print 'step 1'
    yield 1
    print 'step 2'
    yield 3
    print 'step 3'
    yield 5


# 在执行过程当中,遇到yield就中断,下次又继续执行
# 基本上历来不会用next()来调用它,而是直接使用for循环来迭代
o = odd()
print o.next()
print o.next()
print o.next()


# 函数式编程的一个特色就是,容许把函数自己做为参数传入另外一个函数,还容许返回一个函数!
# 函数的名字也是变量
def add(x, y, f):
    return f(x) + f(y)


print(add(-5, 6, abs))


def f(x):
    return x * x


# map()函数接收两个参数,一个是函数,一个是Iterable,
# map将传入的函数依次做用到序列的每一个元素,并把结果做为新的Iterator返回
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print list(r)
# for也能实现,太麻烦
L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
    L.append(f(n))
print(L)
print list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))


# reduce把结果继续和序列的下一个元素作累积计算
# reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
def add(x, y):
    return x + y


print reduce(add, [1, 3, 5, 7, 9]) \
    # 求和运算能够直接用Python内建函数sum(),不必动用reduce。


# print sum([1, 3, 5, 7, 9])


def fn(x, y):
    return x * 10 + y


print reduce(fn, [1, 3, 5, 7, 9])


def char2num(s):
    digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    return digits[s]


print reduce(fn, map(char2num, '13579'))

# 简化
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}


def str2int(s):
    def fn(x, y):
        return x * 10 + y

    def char2num(s):
        return DIGITS[s]

    return reduce(fn, map(char2num, s))


# 用lambda函数进一步简化
def char2num(s):
    return DIGITS[s]


def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s))


print str2int('13579')


# filter()函数用于过滤序列
# 根据返回值是True仍是False决定保留仍是丢弃该元素
def is_odd(n):
    return n % 2 == 1


print list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))


def not_empty(s):
    return s and s.strip()


print list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))

print sorted([36, 5, -12, 9, -21])
print sorted([36, 5, -12, 9, -21], key=abs)
print sorted(['bob', 'about', 'Zoo', 'Credit'])
# 排序应该忽略大小写,按照字母序排序
print sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
print sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)


def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax

    return sum


# 闭包,函数做为返回值
# 返回的函数并无马上执行,而是直到调用了f()才执行。
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
print f1() == f2()  # true,比较的值
print f1 == f2  # false,引用不一样,因此f1()和f2()的调用结果互不影响。


def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i * i

        fs.append(f)
    return fs


# 所有都是9!缘由就在于返回的函数引用了变量i,但它并不是马上执行。
# 等到3个函数都返回时,它们所引用的变量i已经变成了3,所以最终结果为9
# 返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
f1, f2, f3 = count()


def count():
    def f(j):
        def g():
            return j * j

        return g

    fs = []
    for i in range(1, 4):
        fs.append(f(i))  # f(i)马上被执行,所以i的当前值被传入f()
    return fs


f1, f2, f3 = count()  # 1,4,9

# 匿名函数
# 冒号前面的x表示函数参数
print list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))


# 匿名函数lambda x: x * x,实际上就是
def f(x):
    return x * x


# 能够把匿名函数赋值给一个变量,再利用变量来调用该函数
# 也能够把匿名函数做为返回值返回
f = lambda x: x * x
print f(4)


# 假设咱们要加强now()函数的功能,好比,在函数调用先后自动打印日志,但又不但愿修改now()函数的定义,
# 这种在代码运行期间动态增长功能的方式,称之为“装饰器”(Decorator)。
def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)

    return wrapper


@log
def now():
    print('2015-3-25')


print now()

# 偏函数:当函数的参数个数太多,须要简化时,使用functools.partial能够建立一个新的函数,
# 这个新函数能够固定住原函数的部分参数,从而在调用时更简单。
int2 = functools.partial(int, base=2)


# 不须要咱们本身定义
def int3(x, base=2):
    return int(x, base)


print int2('1000000')
print int3('1000000')

# 做者
__author__ = 'Michael Liao'


def _private_1(name):
    return 'Hello, %s' % name


def _private_2(name):
    return 'Hi, %s' % name


# 相似_xxx和__xxx这样的函数或变量就是非公开的(private),不该该被直接引用
# 公开greeting()函数,而把内部逻辑用private函数隐藏起来
def greeting(name):
    if len(name) > 3:
        return _private_1(name)
    else:
        return _private_2(name)

  

面向对象

# 面向过程
import logging
import types

std1 = {'name': 'Michael', 'score': 98}
std2 = {'name': 'Bob', 'score': 81}


def print_score(std):
    print('%s: %s' % (std['name'], std['score']))


# 面向对象
class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.score = score

    # self指向建立的实例自己,能够不传
    # 实现数据的封装
    def print_score(self):
        print('%s: %s' % (self.__name, self.score))

    def get_name(self):
        return self.__name

    def set_name(self, name):
        self.__name = name


bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
bart.print_score()
lisa.print_score()
print lisa.get_name(), lisa.score


class Animal(object):
    def run(self):
        print 'Animal is running...'


class Dog(Animal):
    def run(self):
        print 'Dog is running...'


class Cat(Animal):
    def run(self):
        print 'Cat is running...'


# 多态
def run_twice(animal):
    if (isinstance(animal, Animal)):
        animal.run()
    else:
        print "类型错误"


print run_twice(Cat())
print run_twice(Student('Bart Simpson', 59));

# 对于class的继承关系来讲,使用type()就很不方便。
# 咱们要判断class的类型,可使用isinstance()函数。
print type('abc') == types.StringType
print type(u'abc') == types.UnicodeType
print type([]) == types.ListType
print type(str) == types.TypeType

print  dir('ABC')


class Student(object):
    pass


s = Student()
s.name = 'Michael'  # 动态给实例绑定一个属性
print s.name


def set_age(self, age):  # 定义一个函数做为实例方法
    self.age = age


from types import MethodType

s.set_age = MethodType(set_age, s, Student)  # 给实例绑定一个方法
s.set_age(25)  # 调用实例方法
print s.age  # 测试结果
s2 = Student()  # 建立新的实例


# print s2.set_age(25)  # 尝试调用方法,不能


def set_score(self, score):
    self.score = score


# 为了给全部实例都绑定方法,能够给class绑定方法
Student.set_score = MethodType(set_score, None, Student)


# 定义一个特殊的__slots__变量,来限制该class能添加的属性,但对子类不起做用
class Student(object):
    __slots__ = ('name', 'age')  # 用tuple定义容许绑定的属性名称


s = Student()  # 建立新的实例
s.name = 'Michael'  # 绑定属性'name'
s.age = 25  # 绑定属性'age'


# s.score = 99  # 不能绑定属性'score'

# 该属性不是直接暴露的,而是经过getter和setter方法来实现
class Student(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value


s = Student()
s.score = 60  # OK,实际转化为s.set_score(60)
s.score  # OK,实际转化为s.get_score()
# s.score = 9999
print s.score  # 实际转化为s.get_score()


# 还能够定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:
class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2014 - self._birth


# 能够多继承
# class Dog(Mammal, RunnableMixin, CarnivorousMixin):
#     pass


# 定制类
# __str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串
class Student(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return 'Student object (name=%s)' % self.name

    __repr__ = __str__


s = Student('Michael')
print s
print Student('Michael')


# 要表现得像list那样按照下标取出元素,须要实现__getitem__()方法
class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a


f = Fib()


# print f(0), f(100)

# 只有在没有找到属性的状况下,才调用__getattr__,已有的属性,不会在__getattr__中查找。
class Student(object):

    def __getattr__(self, attr):
        if attr == 'age':
            # return 25
            return lambda: 25  # 能够retrun函数,调用方式不同了
        raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)


s = Student()
print s.age()


class Chain(object):

    def __init__(self, path=''):
        self._path = path

    def __getattr__(self, path):
        return Chain('%s/%s' % (self._path, path))

    def __str__(self):
        return self._path


print Chain().status.user.timeline.list


# 任何类,只须要定义一个__call__()方法,就能够直接对实例进行调用(像方法同样)
class Student(object):
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print('My name is %s.' % self.name)


s = Student('Michael')
print s()


# 怎么判断一个变量是对象仍是函数呢?
# print callable(Student())
# print callable([1, 2, 3])

def foo(s):
    return 10 / int(s)


def bar(s):
    return foo(s) * 2


# logging模块能够很是容易地记录错误信息
def main():
    try:
        bar('0')
    except StandardError, e:
        logging.exception(e)
        print 'Error!'
    finally:
        print 'finally...'


# 只要main()捕获到了,就能够处理
print main()


# assert的意思是,表达式n != 0应该是True,不然,后面的代码就会出错。
# 若是断言失败,assert语句自己就会抛出AssertionError:
def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n


def main():
    foo('0')


# 和assert比,logging不会抛出错误,并且能够输出到文件
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print 10 / n

  

线程

# 新线程执行的代码:
# 主线程实例的名字叫MainThread,子线程的名字在建立时指定,咱们用LoopThread命名子线程
import threading
import time


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

# 线程间通信问题(生产者消费者)
# 假定这是你的银行存款:
balance = 0


def change_it(n):
    # 先存后取,结果应该为0:
    global balance
    balance = balance + n
    balance = balance - n


# def run_thread(n):
#     for i in range(100000):
#         change_it(n)

# 须要上锁
lock = threading.Lock()


def run_thread(n):
    for i in range(100000):
        # 先要获取锁:
        lock.acquire()
        try:
            # 放心地改吧:
            change_it(n)
        finally:
            # 改完了必定要释放锁:
            lock.release()


t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print balance

# 建立全局ThreadLocal对象
# 每一个Thread对它均可以读写student属性,但互不影响。也不用加锁
# ThreadLocal最经常使用的地方就是为每一个线程绑定一个数据库链接,HTTP请求,用户身份信息等,
# 这样一个线程的全部调用到的处理函数均可以很是方便地访问这些资源。
local_school = threading.local()


def process_student():
    print 'Hello, %s (in %s)' % (local_school.student, 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')
t1.start()
t2.start()
t1.join()
t2.join()


# 协程
# consumer函数是一个generator(生成器),把一个consumer传入produce后:
# 首先调用c.next()启动生成器;
# 而后,一旦生产了东西,经过c.send(n)切换到consumer执行;
# consumer经过yield拿到消息,处理,又经过yield把结果传回;

# produce拿到consumer处理的结果,继续生产下一条消息;
# produce决定不生产了,经过c.close()关闭consumer,整个过程结束。
# 整个流程无锁,由一个线程执行,produce和consumer协做完成任务,因此称为“协程”,而非线程的抢占式多任务。

def consumer():
    r = ''
    while True:
        n = yield r
        if not n:
            return
        print('[CONSUMER] Consuming %s...' % n)
        time.sleep(1)
        r = '200 OK'


def produce(c):
    c.next()
    n = 0
    while n < 5:
        n = n + 1
        print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)
        print('[PRODUCER] Consumer return: %s' % r)
    c.close()


if __name__ == '__main__':
    c = consumer()
    produce(c)

  

IO操做

# os模块封装了操做系统的目录和文件操做,要注意这些函数有的在os模块中,有的在os.path模块中
# 要读取二进制文件,好比图片、视频等等,用'rb'模式打开文件
import codecs
import json
import os
import random
import threading
import time

try:
    f = open('D:\heihei.txt', 'r')
    print f.read()
    # 若是文件很小,read()一次性读取最方便;
    # 若是不能肯定文件大小,反复调用read(size)比较保险;
    # 若是是配置文件,调用readlines()最方便
    for line in f.readlines():
        print(line.strip())  # 把末尾的'\n'删掉
finally:
    if f:
        f.close()

# 上面太繁琐引入了with语句来自动帮咱们调用close()方法
with open('D:\heihei.txt', 'r') as f:
    print f.read()

# 判断文件是否存在
if os.path.isdir(f):
    pass
else:
    os.makedirs(f)


# 直接读出unicode
# with codecs.open('D:/gbk.txt', 'r', 'gbk') as f:
#     f.read() # u'\u6d4b\u8bd5'


print os.name  # 操做系统名字
print os.environ
print os.getenv('PATH')

# 查看当前目录的绝对路径:
print os.path.abspath('.')
# # 在某个目录下建立一个新目录,
# # 首先把新目录的完整路径表示出来:
# os.path.join(os.path.abspath('.'), 'testdir')
# # 而后建立一个目录:
# os.mkdir(os.path.abspath('.') + '/testdir')
# # 删掉一个目录:
# os.rmdir(os.path.abspath('.') + '/testdir')

# 分离路径和名字
print os.path.split('/Users/michael/testdir/file.txt')
# 能够轻松拿到扩展名
print os.path.splitext('/path/to/file.txt')

# 对文件重命名(须要有这个文件)
# os.rename('test.txt', 'test.py')
# 删除文件
# os.remove('test.py')

# 列出当前目录下的全部目录
print [x for x in os.listdir('.') if os.path.isdir(x)]
# 列出全部的.py文件
print [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1] == '.py']

try:
    import cPickle as pickle
except ImportError:
    import pickle

# 序列化
d = dict(name='Bob', age=20, score=88)
# 方法1:pickle.dumps()方法把任意对象序列化成一个str,而后,就能够把这个str写入文件
s = pickle.dumps(d)
# 反序列化
d = pickle.loads(s)
print d

# 方法2:pickle.dump()直接把对象序列化后写入一个file-like Object:
f = open('dump.txt', 'wb')
pickle.dump(d, f)
f.close()
# 反序列化
f = open('dump.txt', 'rb')
d = pickle.load(f)
f.close()
print d

# 字典转化成json,也有俩种方法
d = dict(name='Bob', age=20, score=88)
s = json.dumps(d)
print json.loads(s)


# 对象序列号
class Student(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score


s = Student('Bob', 20, 88)


def student2dict(std):
    return {
        'name': std.name,
        'age': std.age,
        'score': std.score
    }


# Student实例首先被student2dict()函数转换成dict,而后再被顺利序列化为JSON
print(json.dumps(s, default=student2dict))
# 把任意class的实例变为dict
s = json.dumps(s, default=lambda obj: obj.__dict__)
print(s)


# 反序列化
def dict2student(d):
    return Student(d['name'], d['age'], d['score'])


print(json.loads(s, object_hook=dict2student))

# 进程和线程
# mac里这样建立
# print 'Process (%s) start...' % os.getpid()
# pid = os.fork()  # 建立一个进程
# if pid == 0:
#     print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid())
# else:
#     print 'I (%s) just created a child process (%s).' % (os.getpid(), pid)

from multiprocessing import Process, Pool, Queue


# windows下,子进程要执行的代码
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 'Process will start.'
    p.start()
    p.join()
    print 'Process end.'


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()
    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.'


# 进程间通讯
# 写数据进程执行的代码:
def write(q):
    for value in ['A', 'B', 'C']:
        print 'Put %s to queue...' % value
        q.put(value)
        time.sleep(random.random())


# 读数据进程执行的代码:
def read(q):
    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()

  

网络编程

# 客户端
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 创建链接:
s.connect(('192.168.202.2', 9999))
# 接收欢迎消息:
print s.recv(1024)
for data in ['Michael', 'Tracy', 'Sarah']:
    # 发送数据:
    s.send(data)
    print s.recv(1024)
s.send('exit')
s.close()


# tcp
# 服务器要可以区分一个Socket链接是和哪一个客户端绑定的。
# 一个Socket依赖4项:服务器地址、服务器端口、客户端地址、客户端端口来惟一肯定一个Socket。
# 建立一个socket:
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 创建链接:
s.connect(('www.sina.com.cn', 80))
# 发送数据:
s.send('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 = ''.join(buffer)
# 关闭链接:
s.close()

header, html = data.split('\r\n\r\n', 1)
print header
# 把接收的数据写入文件:
with open('sina.html', 'wb') as f:
    f.write(html)

  

# 服务端
def tcplink(sock, addr):
    print 'Accept new connection from %s:%s...' % addr
    sock.send('Welcome!')
    while True:
        data = sock.recv(1024)
        time.sleep(1)
        if data == 'exit' or not data:
            break
        sock.send('Hello, %s!' % data)
    sock.close()
    print 'Connection from %s:%s closed.' % addr


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口:
s.bind(('192.168.202.2', 9999))
s.listen(5)
print 'Waiting for connection...'
while True:
    # 接受一个新链接:
    sock, addr = s.accept()
    # 建立新线程来处理TCP链接:
    t = threading.Thread(target=tcplink, args=(sock, addr))
    t.start()