美文网首页
python 杂记

python 杂记

作者: d56eed656c00 | 来源:发表于2017-11-16 16:31 被阅读21次

    进程

    • fork()函数
      Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。

    子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

    Python的os模块封装了常见的系统调用,其中就包括fork,可以在Python程序中轻松创建子进程:

    import os
    print('process %s is start' % os.getpid())
    pid = os.fork()
    print(pid)
    if pid==0:
        print('fatherID: %s    childID :%s' % (os.getppid(),os.getpid()))
    else:
        print('fatherID: %s    childID :%s' % (os.getpid(),pid))
    

    name == 'main'

    • if name=='main': 是将本模块中的代码进行隔绝,使得该模块被调用时不想被执行的代码不会执行。满足条件意味着是运行的本模块而不是被调用。参考这里写链接内容

    线程锁

    import time,threading
    blance =0
    def thread_change(n):
        global blance
        blance =blance+1
        blance =blance-1
    
    lock = threading.Lock()
    def thread_run(n):
        for i in range(1000000):
            # thread_change(n) #如果不使用线程锁就会出现错误
            lock.acquire()
            try:
                thread_change(n)
            finally:
                lock.release()
    #创建两个线程运行thread_run
    f1 = threading.Thread(target=thread_run,args=(5,))
    f2 = threading.Thread(target=thread_run,args=(8,))
    f1.start()
    f2.start()
    f1.join()
    f2.join()
    print(blance)
    

    正则表达式

    • 字符匹配
    # 匹配类型的
    .  #任意字符类型除了换行符,配合re.S使用
    \d #匹配数字
    \w #数字或者字母
    \s #匹配空格
    
    #匹配数量的
    *     #匹配任意数量的字符
    +     #匹配至少一个字符
    ?    #0或1个字符
    {n}   #匹配n个字符
    {n-m} #匹配n-m个字符
    
    #eg:
    code = 'xyx123'
    b = re.findall('x*',code) # ['x', '', 'x', '', '', '', '']
    
    #*与?区别
    code = 'xxixxlovexxyouxx'
    b =re.findall('xx.*xx',code)
    print(b)    #['xxixxlovexxyouxx']
    code = 'xxixxlovexxyouxx'
    b =re.findall('xx.?xx',code)
    print(b)    #['xxixx']
    
    # 非贪心获取
    code = 'xxixx232xxlovexx324xxyouxx'
    b =re.findall('xx(.*?)xx',code)
    print(b)    #['i', 'love', 'you']
    
    • 判断字符串是否是qq邮箱
    import  re
    qq = input()#2.7控制台输入要加''否则会出错。
    if re.match(r'.+@qq\.com',qq):
        print('是qq邮箱')
    else:
        print('不是qq邮箱')
    
    • 字符串切割
    # 'a,b;; c  d'字符串分割
    import re
    print(re.split(r'[\s,;]+','a,b;; c  d'))#+的作用是至少匹配list中的一项。
    # 结果['a', 'b', 'c', 'd']
    
    • 分组
    import  re
    qq = input()
    if re.match(r'^(.+)(@)(qq)(\.com)$',qq):
        print('是qq邮箱')
    else:
        print('不是qq邮箱')
    print(re.match(r'^(.+)(@)(qq)(\.com)$',qq).groups())
    import  re
    qq = input()
    
    #运行结果
    eric@qq.com
    是qq邮箱
    ('eric', '@', 'qq', '.com')
    

    sqlite3

    import sqlite3
    #链接表
    conn = sqlite3.connect('test.db')
    #新建光标
    cursor =  conn.cursor()
    #通过光标执行创建user表
    cursor.execute('create table user (id varchar(20) primary key ,name varchar(20))  ')
    #执行插入一条数据
    cursor.execute('insert into user (id,name) values  ( \'1\',\'eric\')  ')
    #通过光标获取数据条数
    print(cursor.rowcount)
    #关闭光标
    cursor.close()
    #提交事务
    conn.commit()
    #关闭链接
    conn.close()
    
    import sqlite3
    conn =sqlite3.connect('test.db')
    cursor = conn.cursor()
    cursor.execute('select * from user where id = ?',('1',))
    values = cursor.fetchall()
    print(values)
    cursor.close()
    # conn.commit() 只有在改变数据库的动作下才需要提交事务
    conn.close()
    

    mysql 示例

    • 先创建test数据库
    mysqladmin -u root -p create RUNOOB
    
    import mysql.connector
    conn = mysql.connector.connect(user = 'root',password ='admin',database ='test')
    cursor = conn.cursor()
    cursor.execute('create table user (id varchar(20) primary key,name varchar(20))')
    cursor.execute('insert into user (id ,name) values (%s,%s)' , ['1', 'eric'])
    print(cursor.rowcount)
    cursor.close()
    conn.commit()
    
    # 执行查询
    cursor =conn.cursor()
    cursor.execute('select * from user where id =%s' ,('1',))
    values = cursor.fetchall()
    print(values)
    

    SQLAlchemy

    SQLAlchemy用一个字符串表示连接信息:
    
    '数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'
    
    
    import sqlalchemy
    from sqlalchemy import Column, String, create_engine
    from sqlalchemy.ext.declarative import declarative_base
    # 创建ORM 框架对象基类
    from sqlalchemy.orm import sessionmaker
    
    Base  =declarative_base()
    #定义基于基类的对象
    class User(Base):
        #表名字
        __tablename__='user'
        #对应表结构
        id = Column(String(20),primary_key=True)
        name = Column(String(20))
    # 初始化数据连接
    engine = create_engine('mysql+mysqlconnector://root:admin@localhost:3306/test')
    #创建DBSession类,通过两个类创建的DBSession类就可以实现对象化的数据库操作
    DBSession = sessionmaker(bind=engine)
    #
    
    #测试:创建对象进行存储
    
    #
    #创建DBSession对象
    session = DBSession()
    #创建要存储的user对象
    user1 = User(id ='12',name ='eric')# type:__main__.User
    session.add(user1)
    session.commit()
    session.close()
    
    #通过DBSession类对象进行数据的查询
    session = DBSession()
    user2 = session.query(User).filter(User.id=='12').one()
    print(type(user2))
    print(user2)
    

    HTTP格式

    每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。
    
    HTTP协议是一种文本协议,所以,它的格式也非常简单。HTTP GET请求的格式:
    
    GET /path HTTP/1.1
    Header1: Value1
    Header2: Value2
    Header3: Value3
    每个Header一行一个,换行符是\r\n。
    
    HTTP POST请求的格式:
    
    POST /path HTTP/1.1
    Header1: Value1
    Header2: Value2
    Header3: Value3
    
    body data goes here...
    当遇到连续两个\r\n时,Header部分结束,后面的数据全部是Body。
    
    HTTP响应的格式:
    
    200 OK
    Header1: Value1
    Header2: Value2
    Header3: Value3
    
    body data goes here...
    HTTP响应如果包含body,也是通过\r\n\r\n来分隔的。请再次注意,Body的数据类型由Content-Type头来确定,如果是网页,Body就是文本,如果是图片,Body就是图片的二进制数据。
    
    当存在Content-Encoding时,Body数据是被压缩的,最常见的压缩方式是gzip,所以,看到Content-Encoding: gzip时,需要将Body数据先解压缩,才能得到真正的数据。压缩的目的在于减少Body的大小,加快网络传输。
    

    WSGI 接口使用

    • hello.py
    def application(environ,start_response):
        start_response('200 OK',[('Content-Type','text/html')])
        return [b'<h1>hello, web!<h1>']
    
    • server.py
    # 创建一个服务器ip为空,端口8000,处理函数application
    from wsgiref.simple_server import make_server
    
    from hello import application
    
    httpd = make_server('',8001,application)
    print('serving http on port 8001')
    # 开始监听http请求
    httpd.serve_forever()
    

    Flask框架使用

    from flask import Flask
    from flask import request
    
    app = Flask(__name__)
    
    @app.route('/', methods=['GET', 'POST'])
    def home():
        return '<h1>Home</h1>'
    
    @app.route('/signin', methods=['GET'])
    def signin_form():
        return '''<form action="/signin" method="post">
                  <p><input name="username"></p>
                  <p><input name="password" type="password"></p>
                  <p><button type="submit">Sign In</button></p>
                  </form>'''
    
    @app.route('/signin', methods=['POST'])
    def signin():
        # 需要从request对象读取表单内容:
        if request.form['username']=='admin' and request.form['password']=='password':
            return '<h3>Hello, admin!</h3>'
        return '<h3>Bad username or password.</h3>'
    
    if __name__ == '__main__':
        app.run()
    

    yield next() send()

    def h():
        print ('wenchuan')
        m = yield 5  # Fighting!
        print (m)
        d = yield 12
        print ('We are together!')
    c = h()
    x = next(c) #x 获取了yield 5 的参数值 5
    y = c.send('Fighting!')  #y 获取了yield 12 的参数值12
    print ('We will never forget the date', x, '.', y)
    
    # next() 使得阻塞打开,运行到当前yield处
    # send() 使运行到当前yield并给上个yield传值
    # m=yield 5   m会获得send()传过来的值
    # x=next()    x会获得yield的参数5
    

    yield from

    #相当于
    for item in iterater:
        yield item
    

    生成器将任务分给子迭代器

    aiohttp

    • 实现多线程的网络io并发
    # aiohttp 编写一个web服务器 /返回 index  /hello/name  放回 hello name
    import asyncio
    # from copy import name
    
    from aiohttp import web
    
    
    async def index(request):
        await asyncio.sleep(0.5)
        return web.Response(body=b'<h1>Index<h1>',content_type='text/html')
    async def hello(request):
        await asyncio.sleep(0.5)
        text = '<h1>hello,%s<h1>' % request.match_info['name']
        return web.Response(body=text.encode('utf-8'),content_type='text/html')
    #aiohttp的初始化函数
    async def init(loop):
        app = web.Application(loop=loop)
        app.router.add_route('GET','/',index)
        app.router.add_route('GET','/hello/{name}',hello)
        srv = await  loop.create_server(app.make_handler(),'127.0.0.1',8003)
        print('server start at http://127.0.0.1:8000')
        return srv
    loop = asyncio.get_event_loop()
    loop.run_until_complete(init(loop))
    loop.run_forever()
    

    flask

    基于OAuth的授权码模式
    项目练习地址

    OAuth

    阮一峰OAuth
    名词解释:

    
    
        (1) Third-party application:第三方应用程序,本文中又称"客户端"(client),即上一节例子中的"云冲印"。
    
        (2)HTTP service:HTTP服务提供商,本文中简称"服务提供商",即上一节例子中的Google。
    
        (3)Resource Owner:资源所有者,本文中又称"用户"(user)。
    
        (4)User Agent:用户代理,本文中就是指浏览器。
    
        (5)Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
    
        (6)Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。
    
    
    • OAuth工作流程


      这里写图片描述
    
    
        (A)用户打开客户端以后,客户端要求用户给予授权。
    
        (B)用户同意给予客户端授权。
    
        (C)客户端使用上一步获得的授权,向认证服务器申请令牌。
    
        (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
    
        (E)客户端使用令牌,向资源服务器申请获取资源。
    
        (F)资源服务器确认令牌无误,同意向客户端开放资源。
    
    

    爬虫爬取特定内容

    项目地址

    import re
    
    import requests as requests
    
    source = open('source.txt', 'r')
    html = source.read()
    linkList = re.findall('img src="(.*?)" class="lessonimg"', html, re.S)
    i = 1
    for link in linkList:
        print('downloding the %s picture' % i)
        downing = requests.get(link)
        fp = open('pic//' + str(i) + '.jpg', 'wb')
        fp.write(downing.content)
        fp.close()
        i += 1
    
    
    • 从百度爬取二哈
      目前只能单页爬取
    import  re
    
    import requests
    headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0'}
    html = requests.post('http://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E5%93%88%E5%A3%AB%E5%A5%87/pageName=2',headers=headers)
    print(html.headers)
    file = open('test.txt','wb')
    file.write(html.content)
    # 获取图片地址
    
    picUrl = re.findall('"objURL":"(.*?)"',html.text,re.S)
    i = 0
    for each in picUrl:
        i += 1
        if not (i ==16 or  i==22 or i==24):
            picFile = open('dogPic//'+str(i)+'.jpg','wb')
            picContent = requests.get(each)
            #经获取的图片数据写入文件
            picFile.write(picContent.content)
            print('第%d张图片爬取完成'%(i))
        else:
            pass
    

    split(char,num)

    char 为空默认 空格 换行 或 \t
    num 表示分割几次

    pip 安装

    sudo easy_install pip
    

    virtualenv 虚拟环境

    廖雪峰virtualenv

    • 安装
    pip3 virtualevn
    
    • 安装在当前账户目录下
    • /Users/eric/.virtualenvs/


      这里写图片描述
    • 创建一个纯净的独立python3环境
    virtualenv --no-site-packages venv
    
    • 启用虚拟环境
    source venv/bin/activate
    
    • 退出虚拟环境
    deactivate
    

    virtualenvwrapper安装

    安装及初始化

    # 安装
    pip install virtualenvwrapper
    
    # 初始化
    export WORKON_HOME='~/.virtualenvs'
    source /usr/local/bin/virtualenvwrapper.sh
    source ~/.bashrc
    
    # 创建2.7版本的虚拟环境
    mkvirtualenv -p python2.7 env2.7
    
    • 创建一个Python2.7纯净版的虚拟环境
    mkvirtualenv -p python2.7 --no-site-packages py2.7django1.8
    
    • 退出当前环境
    deactivate
    
    • 进入、列出、删除
    workon env
    lsvirtualenv
    rmvirtualenv
    

    找到python安装路径

    Mac

    type -a python3
    

    sublime python配置

    这里写链接内容

    windows 控制台切换python版本

    默认控制台启动的版本是第一个添加环境变量的版本,需要那个就像暂时改动环境变量吧。

    property

    属性参考

    简介:
    通过装饰器将类方法封装成属性。

    class Student(object):
    
        def get_score(self):
            return self._score
    
        def set_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
    

    json转换

    dic = {'name':'eric', 'sex':1}
    json_str = json.dumps(dic)#将字典抓换成json
    print(json_str)
    dic = json.loads(json_str)#将json转换成字典
    print(dic)
    

    相关文章

      网友评论

          本文标题:python 杂记

          本文链接:https://www.haomeiwen.com/subject/puzlvxtx.html