python学习笔记

1、迭代

for value in a.itervalues():    for k, v in a.iteritems():
#a可以是dict, 字符串,list,生成器

判断是否可迭代

from collections import Iterable
isinstance(type, Iterable)

下标迭代

for i, v in enumerate(['a', 'b', 'c']):
    print i, v

生成器

a = [i for i in range(10)]  -> list
a = (i for i in range(10)) -> 生成器
#生成器有a.next()方法,也可以用for
#通过函数得到生成器:yield

斐波那契

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1

2、map/reduce

  • map(f, data),接受一个函数,一个数据
    map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
  • reduce(f, data),接受一个函数,一个数据
    reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)递归的执行函数f
#string转int
def str2int(s):
    def fn(x, y):
        return 10 * x + y
    def char2int(x):
        return {'0': 0, '1':1, '2':2, ..., '9':9} [x] #通过key“x”取出对应的数
    return reduce(fn, map(char2int, s))

3、filter

filter(f, data),接受一个函数,一个数据,根据返回值true/false决定保留还是丢掉

4、sorted

sorted(data[, fn]),接受一个数据,(可选)一个函数,这个函数只需定义二维关系

5、返回函数

在函数内返回值也为函数:

def f(*args):
    def fn():
    return fn

只有在调用时才执行计算:fn()

6、闭包

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

7、匿名函数lambda

关键字lambda表示匿名函数,冒号前表示参数,之后表示表达式,不需要return,只能有一个表达式

8、装饰器

装饰器返回的是一个函数

  • name:一种属性。
    函数对象可以被赋值给变量,通过__name__可以拿到函数名
  • 功能:不修改函数的前提下,增强函数的功能
  • @:函数的装饰符,出现在函数定义的上一行,它将被修饰的函数作为输入参数,并返回修饰后的函数.
def log(func):
    def wrapper(*args, **kw):
        print 'call %s():' % func.__name__
        return func(*args, **kw)
    return wrapper
@log
def now():
    print '2013-12-25'

结果:
>>> now()
call now():
2013-12-25

9、*args **kw

  • *args:非关键字参数,元组
  • **kw:关键字参数,字典

10、偏函数

functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

11、模块

  • init.py
    标志一个模块包,可以为空,也是模块,名称为包名
  • if name==‘main
    当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
  • 作用域
    xxx: 特殊变量,可以被引用
    _xx/__xx:私有
    future

12、面向对象编程OOP

面向对象的设计思想是抽象出Class,根据Class(类)创建Instance(实例)。class既包含数据又包含方法。

__init__方法

第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,仍然可以用默认参数、可变参数和关键字参数。

数据封装

使用类的方法,“包裹”(封装)数据,使数据不外现。
通过Class.name 为类Class增加属性name

访问限制

  • 内部属性不允许外部访问: __xxx;
  • 需要外部能访问不能修改
    定义方法get_xxx(self):return self.__xxx;
    需要外部能修改:定义方法set_xxx(self,xxx): self.__xxx = xxx
    虽然可以访问但是视为私有:_xxx
  • 继承
    子类获得了父类的全部功能;
    子类方法覆盖父类方法(多态)
  • 多态:可以方便的以父类为参数定义函数,实现多个子类
  • “开闭”原则:
    对扩展开放:允许新增Animal子类;对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。
  • 获取对象信息
    type(xxx)
    isinstance(a, sometype)
  • dir():如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list
  • slots = (xxx, yyy):定义允许被外部“赋值”(绑定)的属性,子类不继承父类的slots,除非显示定义
  • @property:装饰器,将方法变成属性调用,同时保留方法的灵活性
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
  • 多重继承Mixin:通过多重继承,一个子类就可以同时获得多个父类的所有功能。class Bat(Mammal, Flyable):pass。java不行。
  • 其他内置方法以自定义定制类:
    • str(self): 用于返回print Class的结果
    • repr():用于返回 Class 回车的结果,可以设置为与__str__()相同
    • iter():用于定义可迭代对象,需要跟next方法一起定义
    • getitem():用于返回按下标访问的对象
    • getattr(self,attr):用于调用没有定义的属性attr时的返回值
    • call():用于定义调用实例

13、调试

  • print
  • assert:断言,替代print。
    assert 判断条件, 否则语句。可以通过 python -o关闭所有断言,此时相当于pass
  • logging:需要import logging,设置logging.basicConfig(level=logging.INFO),用logging.info("")替代print。通过level设置debug,info,warning,error
  • pdb:单步调试。
    python -m pdb python.py 输入1显示代码,输入n执行下一步,输入p 变量名 输出变量,输入q推出
    pdb.set_trace():设置断点。需要import pdb, 到断点自动暂停,p查看变量,c继续
  • 单元测试:(。。。)
  • 文档测试:(。。。)

14、IO编程

  • f = open(’/Users/michael/test.txt’, ‘r’):文件打开,若不存在报错
  • f.read():方法可以一次读取文件的全部内容到内存str
    f.read(size):仅读取size字节
    readline()可以每次读取一行内容,readlines()一次读取所有内容并按行返回list
  • 字符解码:要读取非ASCII编码的文本文件,就必须以二进制模式打开,再解码
>>> f = open('/Users/michael/gbk.txt', 'rb')
>>> u = f.read().decode('gbk')
>>> u
u'\u6d4b\u8bd5'
>>> print u
测试
  • codecs模块帮我们在读文件时自动转换编码,直接读出unicode
import codecs
with codecs.open('/Users/michael/gbk.txt', 'r', 'gbk') as f:
    f.read() # u'\u6d4b\u8bd5'
  • os模块:操作文件系统。
    os.environ: 获取环境变量
    os.getenv(xxx):获取某个环境变量
    os.uname():获取系统详细信息
    os.path:操作文件或目录。shutil,补充模块
    os.path.abspath(’.’):获取当前绝对路径;
    os.path.join(‘xxx’, ‘xxx’):将路径和文件名组合成新路径,可以避免不同操作系统下分隔符问题
    os.path.split(‘xxx/xxx.txt’): 分割路径和文件名
    ps.path.splitext(‘xxx’):得到“文件名”和扩展名
    os.mkdir(‘xxx’):新建
    os.rmdir(‘xxx’):删除
    os.rename(‘xxx’):重命名文件
    os.remove(‘xxx’):删除文件
    os.listdir;os.path.isdir;os.path.isfile
  • 序列化:把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
  • 模块pickle/cPickle
    pickle.dumps(variable)-pickle.loads(str): pickle.dump(variable, file)-pickle.load(file)
  • 模块json:json.dumps-json.loads

15、进程和线程

  • 进程(Process):一个任务
  • 线程(Thread) :进程内的“子任务”
  • multiprocessing模块
    提供了一个Process类来代表一个进程对象
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 'Process will start.'
    p.start() #开始
    p.join() #等待结束
    print 'Process end.'

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() #创建,可以设置可以并行的进程数量
    for i in range(5):
        p.apply_async(long_time_task, args=(i,)) #开始
    print 'Waiting for all subprocesses done...'
    p.close() #结束
    p.join() #等待结束,对pool对象,之前必须调用close,强制结束perminate
    print 'All subprocesses done.'
  • 通信:进程间通信是通过Queue、Pipes等实现的。
  • thread和threading
    thread是低级模块,threading是高级模块,对thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。
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') #创建线程锁:保证同一时间只有一个线程在运行。创建一个锁就是通过threading.Lock()来实现:
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()

当多个线程同时执行lock.acquire()时,只有一个线程能成功地获取锁,然后继续执行代码,其他线程就继续等待直到获得锁为止。全局变量必须加锁

  • GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。
  • threading.local():以threading.current_thread()为key将每个线程的全局变量保存独立保存
  • 所有线程共享进程的内存。线程不如进程稳定。
  • 计算密集型:要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。代码运行效率至关重要。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。
  • IO密集型:对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。

16、正则表达式

*贪婪匹配,?非贪婪匹配
预编译:re.compile(r’^(\d{3})-(\d{3,8})$’)

17、常用模块

datetime

datetime.now();
dt.timestamp();
datetime.fromtimestamp(t);
datetime.utcfromtimestamp(t);
datetime.strptime(‘2015-6-1 18:19:59’, ‘%Y-%m-%d %H:%M:%S’);
now.strftime(’%a, %b %d %H:%M’);
timedelta(hours=10)

collections

namedtuple(‘name’, [‘n1’, ‘n2’,…])命名tuple,并能根据属性引用
deque: deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
defaultdict: dd = defaultdict(lambda: ‘N/A’),key不存在时,返回一个默认值
OrderedDict:OrderedDict的Key会按照插入的顺序排列,不是Key本身排序

Counter

计数器,是dict的子类

from collections import Counter
c = Counter()
for ch in 'programming':
     c[ch] = c[ch] + 1

>>> c
Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})

base64

是一种用64个字符来表示任意二进制数据的方法,常用于在URL、Cookie、网页中传输少量二进制数据。

hashlib

提供了常见的摘要算法,如MD5,SHA1等等。

import hashlib
	md5 = hashlib.md5()
	md5.update('how to use md5 in python hashlib?')#太长可以多次调用update
	print md5.hexdigest()#结果

itertools

itertools.count(1) #产生自然数列
itertools.cycle(xxx)#无限重复xxx
itertools.repeat(‘A’, 10) #重复10次
itertools.takewhile(lambda x: x <= 10, xxx) #将无限序列xxx截取
itertools.chain(‘ABC’, ‘XYZ’)#将一组迭代对象串联起来,形成一个更大的迭代器
itertools.groupby #把迭代器中相邻的重复元素挑出来放在一起
itertools.imap #可以作用于无限序列,返回迭代对象;map作用于有限,返回计算结果
itertools.ifilter #filter的惰性实现

第三方模块

  • https://pypi.org
  • pillow----PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准
  • chardet:检测编码
  • psutil:获取系统信息

18、网络编程

网络通信

两台计算机上的两个进程之间的通信

  • 互联网的协议简称TCP/IP协议:
    IP协议负责把数据从一台计算机通过网络发送到另一台计算机。一个IP包除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。TCP协议则是建立在IP协议之上的。
    TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。
  • Socket:网络编程的一个抽象概念。通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。
  • TCP编程:创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器
  • UDP编程:不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。

电子邮件:

MUA:Mail User Agent——邮件用户代理。即电子邮件软件
MTA:Mail Transfer Agent——邮件传输代理,就是那些Email服务提供商,比如网易、新浪等等
MDA:Mail Delivery Agent——邮件投递代理
发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- 收件人
发邮件时,MUA和MTA使用的协议就是SMTP:Simple Mail Transfer Protocol,后面的MTA到另一个MTA也是用SMTP协议。
收邮件时,MUA和MDA使用的协议有两种:POP:Post Office Protocol,目前版本是3,俗称POP3;IMAP:Internet Message Access Protocol,目前版本是4,优点是不但能取邮件,还可以直接操作MDA上存储的邮件,比如从收件箱移到垃圾箱,等等。

19、数据库

要操作关系数据库,首先需要连接到数据库,一个数据库连接称为Connection;
连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结果。

20、协程

yield
(。。。)
异步IO(。。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值