zoukankan      html  css  js  c++  java
  • Python学习摘录(下)

    常用内建模块

    1:collections模块:集合模块,提供了许多有用的集合类。

    namedtuple

    namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。

    这样一来,我们用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。

    >>> from collections import namedtuple
    >>> Point = namedtuple('Point', ['x', 'y'])
    >>> p = Point(1, 2)
    >>> p.x
    1
    >>> p.y
    2

    deque:为了高效实现插入和删除操作的双向列表,适合用于队列和栈。

    deque除了实现list的append()pop()外,还支持appendleft()popleft(),这样就可以非常高效地往头部添加或删除元素。

    >>> from collections import deque
    >>> q = deque(['a', 'b', 'c'])
    >>> q.append('x')
    >>> q.appendleft('y')

    defaultdict:使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

     dd = defaultdict(lambda: 'N/A')
    dd['key2'] # key2不存在,返回默认值 'N/A'

    OrderedDict:保持Key的顺序,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序。

     od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    >>> od # OrderedDict的Key是有序的
    OrderedDict([('a', 1), ('b', 2), ('c', 3)])

    Counter:一个简单的计数器。

    统计字符出现的个数:

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

    2:hashlib

    Python的hashlib提供了常见的摘要(散列)算法,如MD5,SHA1等等。

    它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。

    md5使用:

    import hashlib
    
    md5 = hashlib.md5()//创建md5实例
    md5.update('how to use md5 in python hashlib?')//使用md5对字符串加密
    print md5.hexdigest()//得到md5加密后的字符串

    sha1使用:

    import hashlib
    
    sha1 = hashlib.sha1()//创建sha1实例
    sha1.update('how to use sha1 in ')//加密
    print sha1.hexdigest()//获取加密后字符串

    摘要算法的正确使用:使用唯一性内容+需要加密的内容+混淆性内容 作为数据库存储的内容。

    通过对原始口令加一个复杂字符串,俗称“加盐”。但是如果加密内容一致,加盐又一致,则会出现相同的存储内容。所以在此基础上再加上唯一性的内容,比如用户名。

    db[username] = get_md5(password + username + 'the-Salt')

    3:itertools

    Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数。

    几个“无限”迭代器:

    count(n)会创建一个无限的迭代器,从n开始一直迭代下去,永不停止。

    cycle(str)会把传入的一个序列无限重复迭代下去。

    repeat(char,num)负责把一个元素无限重复下去,不过如果提供第二个参数就可以限定重复次数

    无限序列虽然可以无限迭代下去,但是通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列:

    >>> natuals = itertools.count(1)//创建一个无限迭代器
    
    >>> ns = itertools.takewhile(lambda x: x <= 10, natuals)//遍历无限迭代器的内容,从中提取符合lambda表达式的内容

    操作迭代器的几个函数:

    chain()可以把一组迭代对象串联起来,形成一个更大的迭代器:

    for c in itertools.chain('ABC', 'XYZ'):
        print c
    # 迭代效果:'A' 'B' 'C' 'X' 'Y' 'Z'

    groupby()把迭代器中相邻的重复元素挑出来放在一起。

    imap()可以作用于无穷序列,并且,如果两个序列的长度不一致,以短的那个为准。当你调用imap()时,并没有进行任何计算,必须用for循环对r进行迭代,才会在每次循环过程中计算出下一个元素。

    同理,ifilter()就是filter()的惰性实现。

    4:XML操作模块

    操作XML有两种方法:DOM和SAX。DOM会把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点。SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。

    正常情况下,优先考虑SAX,因为DOM实在太占内存。

    在Python中使用SAX解析XML非常简洁,通常我们关心的事件是start_elementend_elementchar_data,准备好这3个函数,然后就可以解析xml了。

    from xml.parsers.expat import ParserCreate
    
    #定义三个事件
    class DefaultSaxHandler(object):
        def start_element(self, name, attrs):
            print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))
    
        def end_element(self, name):
            print('sax:end_element: %s' % name)
    
        def char_data(self, text):
            print('sax:char_data: %s' % text)
    
    xml = r'''<?xml version="1.0"?>
    <ol>
        <li><a href="/python">Python</a></li>
        <li><a href="/ruby">Ruby</a></li>
    </ol>
    '''
    
    handler = DefaultSaxHandler()
    parser = ParserCreate()
    parser.returns_unicode = True
    parser.StartElementHandler = handler.start_element
    parser.EndElementHandler = handler.end_element
    parser.CharacterDataHandler = handler.char_data
    parser.Parse(xml)

    如何生成XML呢?最简单也是最有效的生成XML的方法是拼接字符串:

    L = []
    L.append(r'<?xml version="1.0"?>')
    L.append(r'<root>')
    L.append(encode('some & data'))
    L.append(r'</root>')
    return ''.join(L)

    5:HTMLParser

    如何解析HTML呢?

    from HTMLParser import HTMLParser
    from htmlentitydefs import name2codepoint
    
    class MyHTMLParser(HTMLParser):
    
        def handle_starttag(self, tag, attrs):
            print('<%s>' % tag)
    
        def handle_endtag(self, tag):
            print('</%s>' % tag)
    
        def handle_startendtag(self, tag, attrs):
            print('<%s/>' % tag)
    
        def handle_data(self, data):
            print('data')
    
        def handle_comment(self, data):
            print('<!-- -->')
    
        def handle_entityref(self, name):
            print('&%s;' % name)
    
        def handle_charref(self, name):
            print('&#%s;' % name)

    6:强大的第三方图形处理模块——PIL


    首先,要安装PIL。

    然后,就行import相关模块,调用模块内的函数进行图形处理了。

    网络编程

    TCP/IP——Socket通信

    1:客户端通信

    # 导入socket库:
    import socket
    # 创建一个socket:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 建立连接:
    s.connect(('域名', 端口))

    #发送数据
    s.send('内容')
    # 每次最多接收1k字节:
    d = s.recv(1024)
    # 关闭连接:
    s.close()
     

    创建Socket时,AF_INET指定使用IPv4协议,如果要用更先进的IPv6,就指定为AF_INET6SOCK_STREAM指定使用面向流的TCP协议。

    2:服务端通信

    #首先,创建一个基于IPv4和TCP协议的Socket:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #然后绑定监听的地址和端口
    # 监听端口:
    s.bind(('IP地址',端口))
    #调用listen()方法开始监听端口,传入最大监听数
    s.listen(5)
    #通过一个永久循环来接受来自客户端的连接,accept()会等待并返回一个客户端的连接
    
    while True:
        # 接受一个新连接:
        sock, addr = s.accept() #accept方法返回一个含有两个元素的元组(connection,address)
        # 创建新线程来处理TCP连接:
        t = threading.Thread(target=任务函数, args=(sock, addr))
        t.start()
    
     data = sock.recv(1024)#接收内容
     sock.send('Hello, %s!' % data)#发回内容
     sock.close() #关闭socket

    UDP编程

    使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。

    服务端

    #创建服务端socket
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)#SOCK_DGRAM指定了这个Socket的类型是UDP
    # 绑定端口:
    s.bind(('127.0.0.1', 9999))
    
    #无需监听端口,直接接收来自任何客户端的数据
    while True:
        # 接收数据:recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
        data, addr = s.recvfrom(1024) 
        print 'Received from %s:%s.' % addr
        s.sendto('Hello, %s!' % data, addr)

    客户端

    不需要调用connect(),直接通过sendto()给服务器发数据。

    #创建socket
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for data in ['Michael', 'Tracy', 'Sarah']
        # 发送数据
        s.sendto(data, ('服务器IP',端口))
        # 接收数据
        print s.recv(1024)
    s.close()

    数据库

    操作Mysql:

    # 导入MySQL驱动
    >>> import mysql.connector
    >>> conn = mysql.connector.connect(user='数据库账户', password='密码', database='数据库名', use_unicode=True)
    >>> cursor = conn.cursor()//创建一个游标
    # 创建user表
    >>> cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')//执行SQL语句
    # 插入一行记录,注意MySQL的占位符是%s:
    >>> cursor.execute('insert into user (id, name) values (%s, %s)', ['1', 'Michael'])
    >>> cursor.rowcount //获取语句执行结果
    1
    # 提交事务:
    >>> conn.commit()
    >>> cursor.close()
    # 运行查询:
    >>> cursor = conn.cursor()
    >>> cursor.execute('select * from user where id = %s', ('1',))
    >>> values = cursor.fetchall()//查询所有
    >>> values
    [(u'1', u'Michael')]
    # 关闭Cursor和Connection:
    >>> cursor.close()
    True
    >>> conn.close()

    Python中的ORM框架:SQLAlchemy

    # 导入:
    from sqlalchemy import Column, String, create_engine
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.declarative import declarative_base
    
    # 创建对象的基类:
    Base = declarative_base()
    
    # 定义User对象:
    class User(Base):
        # 表的名字:
        __tablename__ = 'user'
    
        # 表的结构:
        id = Column(String(20), primary_key=True)
        name = Column(String(20))
    
    # 初始化数据库连接:
    engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
    # 创建DBSession类型:
    DBSession = sessionmaker(bind=engine)
    
    # 创建session对象:
    session = DBSession()
    # 创建新User对象:
    new_user = User(id='5', name='Bob')
    # 添加到session:
    session.add(new_user)
    # 提交即保存到数据库:
    session.commit()
    # 关闭session:
    session.close()
    
    # 创建Session:
    session = DBSession()
    # 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
    user = session.query(User).filter(User.id=='5').one()
    # 打印类型和对象的name属性:
    print 'type:', type(user)
    print 'name:', user.name
    # 关闭Session:
    session.close()

    Web开发

    PythonWeb提供了一套接口:WSGI:Web Server Gateway Interface。它只要求Web开发者实现一个函数,就可以响应HTTP请求。

    函数接收两个参数:

    • environ:一个包含所有HTTP请求信息的dict对象;

    • start_response:一个发送HTTP响应的函数。start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每个Header用一个包含两个strtuple表示。

    使用web框架

         除了Flask,常见的Python Web框架还有:

    • Django:全能型Web框架;

    • web.py:一个小巧的Web框架;

    • Bottle:和Flask类似的Web框架;

    • Tornado:Facebook的开源异步Web框架

  • 相关阅读:
    zip
    yield
    日记
    cat
    genfromtext
    pytorch易忘
    小程序入门(一)
    (二)连接数据库使用Model对象对数据库进行操作(CRUD)
    (一)Moogose(node.js对数据库进行操作)
    CURD练习
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6946110.html
Copyright © 2011-2022 走看看