zoukankan      html  css  js  c++  java
  • Python3 笔记

    Ubuntu18.04 Python3环境

    默认python3已经安装了, 可能是安装其他应用的时候因为依赖关系安装的.

    安装pip3, 先sudo apt update 一下, apt-cache search python3-pip 看看有没有, 如果没有的话检查一下/etc/apt/sources.list 是否正确, 可以参考以下的source.list

    deb http://cn.archive.ubuntu.com/ubuntu/ bionic main restricted
    deb http://cn.archive.ubuntu.com/ubuntu/ bionic-updates main restricted
    deb http://cn.archive.ubuntu.com/ubuntu/ bionic universe
    deb http://cn.archive.ubuntu.com/ubuntu/ bionic-updates universe
    deb http://cn.archive.ubuntu.com/ubuntu/ bionic multiverse
    deb http://cn.archive.ubuntu.com/ubuntu/ bionic-updates multiverse
    deb http://cn.archive.ubuntu.com/ubuntu/ bionic-backports main restricted universe multiverse
    deb http://security.ubuntu.com/ubuntu bionic-security main restricted
    deb http://security.ubuntu.com/ubuntu bionic-security universe
    deb http://security.ubuntu.com/ubuntu bionic-security multiverse
    

    然后通过 sudo apt install python3-pip 安装

    常用的通过pip3安装的package: pymongo, 

    常用语法

    符号

    // 双斜杠表示地板除, 即先做除法/, 然后向下取整floor. 至少有一方是float时结果为float, 两方都是int时结果为int 

    合并两个Dictionary

    x = {'aa':1, 'bb':2, 'cc':3}
    y = {'aa':5, 'xx':6, 'yy':7}
    z = {**x, **y}
    x.update(y)
    print(x)
    # 输出
    {'aa': 5, 'bb': 2, 'cc': 3, 'xx': 6, 'yy': 7}
    {'aa': 5, 'bb': 2, 'cc': 3, 'xx': 6, 'yy': 7}
    

    两种方法都可以实现dictionary合并, 前者不会修改原先两个dictionary的值

    逻辑判断

    # 空, 非空
    if (x is None)
    if (not x is None)
    
    # dictionary是否包含某key
    if ('name' in x.keys())
    if (not 'name' in x.keys())
    

    字符串操作

    # 赋值时会自动合并
    y = 'Hello ' 'World'
    print(y)
    # substring, 截取从0到100(左边include, 右边exclude)的子串, slice方式不会报数组越界
    print(y[0:3])
    # Hel
    print(y[0:100])
    # Hello World
    print(y[-2:])
    # ld
    

    用%号做字符串赋值

    # 单个字符串
    msg = "he is %s ,his hobby is play" %"xiaoming"
    
    # 多个值
    msg = "he is %s ,his hobby is %s" %("xiaoming","play")
     
    # 百分号转义, 小数限位
    tpl="percent %.2f %%" %78.7658943256
    
    #键值对形式传字典
    tpl="i am %(name)s age %(age)d" %{"name":"小明","age":"18"}
    
    '''
    %c 字符及其ASCII码
    %s 字符串
    %d 有符号整数(十进制)
    %u 无符号整数(十进制)
    %o 无符号整数(八进制)
    %x 无符号整数(十六进制)
    %X 无符号整数(十六进制大写字符)
    %e 浮点数字(科学计数法)
    %E 浮点数字(科学计数法,用E代替e)
    %f 浮点数字(用小数点符号)
    %g 浮点数字(根据值的大小采用%e或%f)
    %G 浮点数字(类似于%g)
    %p 指针(用十六进制打印值的内存地址)
    %n 存储输出字符的数量放进参数列表的下一个变量中
    '''
    

    用format()做字符串赋值

    # 按顺序赋值
    tp1 = "i am {}, age {}, {}".format("seven", 18, 'alex')
    
    # 指定序号赋值
    tp3 = "i am {0}, age {1}, really {0}".format("seven", 18)
    
    # 指定名称赋值, 右侧结构为字典
    tp5 = "i am {name}, age {age}, really {name}".format(name="seven", age=18)
    
    # 指定类型赋值
    a1 = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%},{:c}".format(15, 15, 15, 15, 15, 15.87623,65)
    
    # 指定 序号 + 类型
    a2 = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%},{1:c}".format(15,65)
    
    # 指定 名称 + 类型
    a3 = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%},{cc:c}".format(num=15,cc=65)
    
    ''' 可用类型
        ” 字符串类型 “的参数
            s,格式化字符串类型数据
            空白,未指定类型,则默认是None,同s
        “ 整数类型 ”的参数
            b,将10进制整数自动转换成2进制表示然后格式化
            c,将10进制整数自动转换为其对应的unicode字符
            d,十进制整数
            o,将10进制整数自动转换成8进制表示然后格式化;
            x,将10进制整数自动转换成16进制表示然后格式化(小写x)
            X,将10进制整数自动转换成16进制表示然后格式化(大写X)
        “ 浮点型或小数类型 ”的参数
            e, 转换为科学计数法(小写e)表示,然后格式化;
            E, 转换为科学计数法(大写E)表示,然后格式化;
            f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
            F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
            g, 自动在e和f中切换
            G, 自动在E和F中切换
            %,显示百分比(默认显示小数点后6位)
    '''
    

    .

    List, Tuple 和 Set

    tuple是不可变的, 用括号赋值(也可以不用)

    # tuple的赋值
    tup1 = 'str1',
    tup2 = ('str1',)
    tup3 = 'str1', 'str2'
    tup4 = ('str1', 'str2')
    tup5 = ([1,2,3], 'aa', 12345)

    list是可变的, list的操作与String很像, [a:b]实际上是对原数组的复制, 下面的代码就避免了操作原列表造成无限循环

    for w in words[:]:  # Loop over a slice copy of the entire list.
        if len(w) > 6:
            words.insert(0, w)
    

    list可以使用[[...]] 直接指定下标获得一个副本子序列, 里面的[...]也可以是表达式生成的list

    # 直接下标获取子序列copy
    iris_X_train = iris_X[[0,1,2,3]]
    # 通过list表达式指定
    iris_X_train = iris_X[indices[:-10]]
    

    .对list做运算, 都是直接对list内的元素作运算, 例如, 求得list中每一个元素的平方, 最后得到的也是同样元素个数的list

    # 求方差
    square_error = (iris_y_result - iris_y_test)**2
    

    .

    常用内置函数

    bin(x) 将一个整数转换为二进制值的字符串, 以 0b 开头(如果是负数则是 -0b)

    enumerate() 用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列, 同时列出数据和数据下标, 一般用在 for 循环当中, 可以指定下标开始值, 如 enumerate(seasons, start=1)

    id(object) 获取对象的全局唯一标识值. 注意, 如果两个对象的生命周期没有重叠, 可能会使用相同的对象id值

    input(prompt) 用于命令行执行中, 暂停并弹出输入提示, 返回值是输入的字符串

    len(x) 计算长度, 可以作用于序列或集合, a sequence (such as a string, bytes, tuple, list, or range) or a collection (such as a dictionary, set, or frozen set).

    list(iterable) 创建一个和iterable数组的元素一样次序也一样的list

    map(func, list) 接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回

    zip(*iterables) 合并参数中的多个iterable里的元素, 按原顺序, 不要求元素个数一致, 但是结果中只包含最短那个的个数

    常用模块

    HTTP请求. Requests模块

    使用手册 http://docs.python-requests.org/zh_CN/latest/api.html

    使用举例

    import requests
    
    def requestGet(url, encoding='UTF-8', tout=20, retries=10):
        count = 0
        while True:
            count += 1
            if (count > retries):
                print('Exceed retry limit')
                return None
            try:
                response = requests.get(url, timeout=tout)
                response.encoding = encoding
                return response.text
            except requests.ReadTimeout:
                print('ReadTimeout')
                continue
            except ConnectionError:
                print('ConnectionError')
                continue
            except requests.RequestException:
                print('RequestException')
                continue
    

    注意: 抓取GB2312网页时, encoding建议使用GB18030, 避免部分特殊文字乱码

    在Requests中保持session信息

    session = requests.session()
    
    # 然后就可以用session来进行各种http请求
    session.headers.update({
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0',
        'Referer': config.base_url + '/default/',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
    })
    #print(session.headers)
    #print(session.cookies.get_dict())
    
    post_data = {'id':user_name,'passwd': user_pass}
    rs = session.post(config.base_url + '/bbslogin1203.php', post_data, proxies=config.proxies)
    print(session.cookies.get_dict())
    

    在Reqeusts中使用代理

    如果使用socks5代理,需要安装pysocks (pip3 install pysocks)

    response = session.get(url, timeout=tout, proxies=dict(
        http='socks5://user:pass@host:port',
        https='socks5://user:pass@host:port'))
    

    各种代理的参数格式

    # SOCKS5 proxy for HTTP/HTTPS
    proxiesDict = {
        'http' : "socks5://1.2.3.4:1080",
        'https' : "socks5://1.2.3.4:1080"
    }
    
    # SOCKS4 proxy for HTTP/HTTPS
    proxiesDict = {
        'http' : "socks4://1.2.3.4:1080",
        'https' : "socks4://1.2.3.4:1080"
    }
    
    # HTTP proxy for HTTP/HTTPS
    proxiesDict = {
        'http' : "1.2.3.4:1080",
        'https' : "1.2.3.4:1080"
    }
    

      

    Mongodb 操作. Pymongo模块

    使用举例

    import pymongo
    
    # 连接mongodb
    client = pymongo.MongoClient('172.17.0.2', 27017)
    # 选择db
    db = client.db_1
    # 选择collection
    tb_user = db['user']
    # count
    total = tb_user.count_documents({})
    # select one
    dummy = tb_user.find_one({'_id': name})
    # select all, and sort
    allusers = tb_user.find().sort('posts', -1)
    # insert or save
    tb_user.save(user)
    

    Collection级别的操作

    # 创建索引
    collection_demo.create_index([('field1', pymongo.ASCENDING)])
    

    检查索引是否存在, 存在则删除索引

        indexes = board_col.list_indexes()
        for index in indexes:
            print(index)
            print(index['name'])
            if (index['name'] == 'author_text_created_at_-1'):
                board_col.drop_index('author_text_created_at_-1')
        # 创建联合索引
        board_col.create_index([('author', pymongo.TEXT),('created_at', pymongo.DESCENDING)])
    

      

    如果要在python中直接执行mongo 命令, 需要使用 eval(), 例如以下的语句用于将多个同构的collection合并到同一个collection

    for board in boards:
        tb_current = rbcommon.db['deb_' + str(board['_id'])]
        if (not tb_current is None):
            current_total = tb_current.find().count()
            print(str(board['_id']) + ', ' + board['name'] + ', ' + board['name2'] + ', ' + str(current_total))
            rbcommon.db.eval('db.deb_'+ str(board['_id']) +'.find({}).forEach(function(u) {db.deb_all.save(u);})')
    

    count_documents()的坑

    对于数据量很大的collection, 尽量不要使用这个方法, 因为这个方法实际上需要遍历所有documents, 会非常慢. 可以使用 estimated_document_count() 这个方法, 这个是从collection的metadata中读取的缓存的documents数量, 如果此时collection正在写入, 可能会与实际数量有出入.

    YAML配置文件读取

    import yaml
    
    # 获取当前文件的路径, 注意: 是common.py路径, 不带slash, 不是引用common的文件的路径, 
    # 可以用 os.path.realpath(__file__) 测试
    rootPath = os.path.dirname(__file__)
    print(rootPath)
    configPath = os.path.join(rootPath,'config.yml')
    print(configPath)
    
    with open(configPath, 'r') as ymlfile:
        cfg = yaml.load(ymlfile)
    
    # yaml会自动将长得像数字的值, 转换为数字类型. 下面是使用配置参数值的方式
    mongoclient = pymongo.MongoClient(cfg['mongo']['host'], cfg['mongo']['port'])
    db = mongoclient[cfg['mongo']['db']]
    tb_section = db['section']
    

    .

    常见问题

    循环中出现 pymongo.errors.CursorNotFound: cursor id xxx not found 错误

    默认mongo server维护连接的时间窗口是十分钟, 默认单次从 server获取数据是101条或者 大于1M小于16M的数据, 所以默认情况下如果循环中的某步在10分钟内未能处理完数据, 则抛出异常. 解决办法为使用no_cursor_timeout = True 参数

    allBoards = rbcommon.tb_board.find({}, no_cursor_timeout = True).sort('post_count', -1)
    for board in allBoards:
        # 0:through out mode, 1:increament mode
        readBoard(board)
    

    .

  • 相关阅读:
    数据结构与算法JavaScript (一) 栈
    js架构设计模式——前端MVVM框架设计及实现(二)
    js架构设计模式——前端MVVM框架设计及实现(一)
    js架构设计模式——MVC,MVP 和 MVVM 的图示及简单明了的区别说明
    js架构设计模式——你对MVC、MVP、MVVM 三种组合模式分别有什么样的理解?
    js面向对象oop编程
    js模块化开发——前端模块化
    SPRING 集成 activemq 的 topic 模式
    linux yum 本地源配置
    ORACLE 导入的问题
  • 原文地址:https://www.cnblogs.com/milton/p/10102367.html
Copyright © 2011-2022 走看看