zoukankan      html  css  js  c++  java
  • typing模块

    一 前言

    Python是一门弱类型的语言,很多时候我们可能不清楚函数参数类型或者返回值类型,很有可能导致一些类型没有指定方法,在写完代码一段时间后回过头看代码,很可能忘记了自己写的函数需要传什么参数,返回什么类型的结果,就不得不去阅读代码的具体内容,降低了阅读的速度,typing模块可以很好的解决这个问题。

    python3.5以上版本,typing模块提高代码健壮性

    二 typing模块的作用

    • 类型检查,防止运行时出现参数和返回值类型不符合。
       
    • 作为开发文档附加说明,方便使用者调用时传入和返回参数类型。
       
    • 该模块加入后并不会影响程序的运行,不会报正式的错误,只有提醒。

    注意:typing模块只有在python3.5以上的版本中才可以使用,pycharm目前支持typing检查

    三 typing模块的常用方式

    from typing import List, Tuple, Dict
    
    def test(a: int, string: str, f: float, b: bool) -> Tuple[List, Tuple, Dict, bool]:
        ll=[1,2,3,4]
        tup = (string, a, string)
        dic = {"xxx": f}
        boo = b
        return ll, tup, dic, boo
    
    print(test(12, "lqz", 2.3, False))

    注意:

    • 在传入参数时通过“参数名:类型”的形式声明参数的类型;

    • 返回结果通过"-> 结果类型"的形式声明结果的类型。

    • 在调用的时候如果参数的类型不正确pycharm会有提醒,但不会影响程序的运行。

    • 对于如list列表等,还可以规定得更加具体一些,如:“-> List[str]”,规定返回的是列表,并且元素是字符串。

    三 typing常用的类型

    • int,long,float: 整型,长整形,浮点型;

    • bool,str: 布尔型,字符串类型;

    • List, Tuple, Dict, Set:列表,元组,字典, 集合;

    • Iterable,Iterator:可迭代类型,迭代器类型;

    • Generator:生成器类型;

    python天生支持多态,迭代器中的元素可能多种

    from typing import List, Union
    
    def func(a: int, string: str) -> List[int or str]:
        list1 = []
        list1.append(a)
        list1.append(string)
        return list1
    
    def get_next_id() -> Union[int, None]:
        return 1
        return None
    # 使用or关键字表示多种类型,也可以用Union

    一 什么是uuid

    uuid是128位的全局唯一标识符(univeral unique identifier),通常用32位的一个字符串的形式来表现。有时也称guid(global unique identifier),C#语言中使用。python中自带了uuid模块来进行uuid的生成和管理工作

    • UUID —— Universally Unique IDentifier  Python中称为 UUID
    • GUID —— Globally Unique IDentifier     C#中称为 GUID

    它是通过MAC地址、 时间戳、 命名空间、 随机数、 伪随机数来保证生成ID的唯一性,,有着固定的大小( 128 bit位 ),通常由 32 字节的字符串(十六进制)表示

    它的唯一性和一致性特点,使得可以无需注册过程就能够产生一个新的UUID;UUID可以被用作多种用途, 既可以用来短时间内标记一个对象,也可以可靠的辨别网络中的持久性对象

    二 uuid有什么用

    很多应用场景需要一个id,但是又不要求这个id 有具体的意义,仅仅用来标识一个对象。常见的用处有数据库表的id字段;用户session的key值;前端的各种UI库,因为它们通常需要动态创建各种UI元素,这些元素需要唯一的id, 这时候就需要使用UUID了。例如:一个网站在存储视频、图片等格式的文件时,这些文件的命名方式就可以采用 UUID生成的随机标识符,避免重名的出现

    三 Python中uuid模块

    UUID主要有五个算法,也就是五种方法来实现

    python的uuid模块提供的UUID类和函数uuid1(),uuid3(),uuid4(),uuid5() 来生成1, 3, 4, 5各个版本的UUID ( 需要注意的是:python中没有uuid2()这个函数)。

    • uuid.uuid1(node clock_seq)
    #   基于时间戳
    #   使用主机ID, 序列号, 和当前时间来生成UUID, 可保证全球范围的唯一性.
    #   但由于使用该方法生成的UUID中包含有主机的网络地址, 因此可能危及隐私.
    #   该函数有两个参数, 如果 node 参数未指定, 系统将会自动调用 getnode() 函数来获取主机的硬件(mac)地址.
    #   如果 clock_seq  参数未指定系统会使用一个随机产生的14位序列号来代替.
    import uuid
    print(uuid.uuid1())
    • uuid.uuid3(namespace, name)
    #   通过计算名字和命名空间的MD5散列值得到,保证了同一命名空间中不同名字的唯一性,
    #   和不同命名空间的唯一性,***但同一命名空间的同一名字生成相同的uuid****。
    print(uuid.uuid3(uuid.NAMESPACE_URL,'python'))
    print(uuid.uuid3(uuid.NAMESPACE_URL,'python'))
    • uuid.uuid4() : 基于随机数
    #   通过随机数来生成UUID. 使用的是伪随机数有一定的重复概率.
    print(uuid.uuid4())
    • uuid.uuid5(namespace, name)
    #   通过计算命名空间和名字的SHA-1散列值来生成UUID, 算法与 uuid.uuid3() 相同
    print(uuid.uuid5(uuid.NAMESPACE_URL,'python'))

    四 总结

    1 Python中没有基于 DCE 的,所以uuid2可以忽略
    2 uuid4存在概率性重复,由无映射性
    3 若在Global的分布式计算环境下,最好用uuid1
    4 若有名字的唯一性要求,最好用uuid3或uuid5

    subprocess模块

    subprocess模块允许你去创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等。更多查看官网:https://docs.python.org/2/library/subprocess.html?highlight=subprocess#frequently-used-arguments

    import subprocess
    import subprocess
    '''
    sh-3.2# ls /Users/nick/Desktop |grep txt$
    mysql.txt
    tt.txt
    事物.txt
    '''
    
    res1 = subprocess.Popen('ls /Users/jieli/Desktop',
                            shell=True,
                            stdout=subprocess.PIPE)
    res = subprocess.Popen('grep txt$',
                           shell=True,
                           stdin=res1.stdout,
                           stdout=subprocess.PIPE)
    
    print(res.stdout.read().decode('utf-8'))
    
    # 等同于上面,但是上面的优势在于,一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep
    res1 = subprocess.Popen('ls /Users/jieli/Desktop |grep txt$',
                            shell=True,
                            stdout=subprocess.PIPE)
    print(res1.stdout.read().decode('utf-8'))
    
    # windows下:
    # dir | findstr 'test*'
    # dir | findstr 'txt$'
    res1 = subprocess.Popen(r'dirC:UsersAdministratorPycharmProjects	est函数备课',
                            shell=True,
                            stdout=subprocess.PIPE)
    res = subprocess.Popen('findstr test*',
                           shell=True,
                           stdin=res1.stdout,
                           stdout=subprocess.PIPE)
    
    # subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码
    print(res.stdout.read().decode('gbk'))

    shutil模块

    高级的文件、文件夹、压缩包处理模块。

    import shutil
    
    # shutil.copyfileobj(fsrc, fdst[, length]),将文件内容拷贝到另一个文件中
    shutil.copyfileobj(open('old.xml', 'r'), open('new.xml', 'w'))
    
    
    # shutil.copyfile(src, dst),拷贝文件
    shutil.copyfile('f1.log', 'f2.log')  # 目标文件无需存在
    
    
    # shutil.copymode(src, dst),仅拷贝权限。内容、组、用户均不变
    shutil.copymode('f1.log', 'f2.log')  # 目标文件必须存在
    
    
    # shutil.copystat(src, dst),仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
    shutil.copystat('f1.log', 'f2.log')  # 目标文件必须存在
    
    
    # shutil.copy(src, dst),拷贝文件和权限
    shutil.copy('f1.log', 'f2.log')
    
    
    # shutil.copy2(src, dst),拷贝文件和状态信息
    shutil.copy2('f1.log', 'f2.log')
    
    
    # shutil.ignore_patterns(*patterns)
    # shutil.copytree(src, dst, symlinks=False, ignore=None),递归的去拷贝文件夹
    # 目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
    shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    
    
    # shutil.rmtree(path[, ignore_errors[, onerror]]),递归的去删除文件
    shutil.rmtree('folder1')
    
    
    # shutil.move(src, dst),递归的去移动文件,它类似mv命令,其实就是重命名
    shutil.move('folder1', 'folder3')
    
    
    # shutil.make_archive(base_name, format, ...),创建压缩包并返回文件路径,例如:zip、tar
    '''
    base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,如 data_bak = >保存至当前路径;/ tmp/data_bak = >保存至/tmp/
    format:压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    root_dir:要压缩的文件夹路径(默认当前目录)
    owner:用户,默认当前用户
    group:组,默认当前组
    logger:用于记录日志,通常是logging.Logger对象
    '''
    
    # 将 /data 下的文件打包放置当前程序目录
    import shutil
    ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
    
    # 将 /data下的文件打包放置 /tmp/目录
    ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
    View Code
    # shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
    import zipfile
    
    # 压缩
    z = zipfile.ZipFile('laxi.zip', 'w')
    z.write('a.log')
    z.write('data.data')
    z.close()
    
    # 解压
    z = zipfile.ZipFile('laxi.zip', 'r')
    z.extractall(path='.')
    z.close()
    zipfile压缩解压缩
    import tarfile
    
    # 压缩
    t=tarfile.open('/tmp/egon.tar','w')
    t.add('/test1/a.py',arcname='a.bak')
    t.add('/test1/b.py',arcname='b.bak')
    t.close()
    
    
    # 解压
    t=tarfile.open('/tmp/egon.tar','r')
    t.extractall('/egon')
    t.close()
    tarfile压缩解压缩

    xml简介

    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

    xml的格式如下,就是通过<>节点来区别数据结构的:

    <?xml version="1.0"?>
    <data>
        <country name="Liechtenstein">
            <rank updated="yes">2</rank>
            <year>2008</year>
            <gdppc>141100</gdppc>
            <neighbor name="Austria" direction="E"/>
            <neighbor name="Switzerland" direction="W"/>
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>
            <year>2011</year>
            <gdppc>59900</gdppc>
            <neighbor name="Malaysia" direction="N"/>
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>
            <year>2011</year>
            <gdppc>13600</gdppc>
            <neighbor name="Costa Rica" direction="W"/>
            <neighbor name="Colombia" direction="E"/>
        </country>
    </data>
    View Code

    Python使用xml

    xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

    # print(root.iter('year')) #全文搜索
    # print(root.find('country')) #在root的子节点找,只找一个
    # print(root.findall('country')) #在root的子节点找,找所有
    
    import xml.etree.ElementTree as ET
    
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
    print(root.tag)
    
    #遍历xml文档
    for child in root:
        print('========>', child.tag, child.attrib, child.attrib['name'])
        for i in child:
            print(i.tag, i.attrib, i.text)
    
    #只遍历year 节点
    for node in root.iter('year'):
        print(node.tag, node.text)
    #---------------------------------------
    
    import xml.etree.ElementTree as ET
    
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
    
    #修改
    for node in root.iter('year'):
        new_year = int(node.text) + 1
        node.text = str(new_year)
        node.set('updated', 'yes')
        node.set('version', '1.0')
    tree.write('test.xml')
    
    #删除node
    for country in root.findall('country'):
        rank = int(country.find('rank').text)
        if rank > 50:
            root.remove(country)
    
    tree.write('output.xml')
    
    #在country内添加(append)节点year2
    import xml.etree.ElementTree as ET
    tree = ET.parse("a.xml")
    root = tree.getroot()
    for country in root.findall('country'):
        for year in country.findall('year'):
            if int(year.text) > 2000:
                year2 = ET.Element('year2')
                year2.text = '新年'
                year2.attrib = {'update': 'yes'}
                country.append(year2)  #往country节点下添加子节点
    
    tree.write('a.xml.swap')
    View Code
    import xml.etree.ElementTree as ET
    
    new_xml = ET.Element("namelist")
    name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
    age = ET.SubElement(name, "age", attrib={"checked": "no"})
    sex = ET.SubElement(name, "sex")
    sex.text = '33'
    name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
    age = ET.SubElement(name2, "age")
    age.text = '19'
    
    et = ET.ElementTree(new_xml)  #生成文档对象
    et.write("test.xml", encoding="utf-8", xml_declaration=True)
    
    ET.dump(new_xml)  #打印生成的格式
    自己创建xml文档
  • 相关阅读:
    request.getParameter() 、 request.getInputStream()和request.getReader() 使用体会
    HTTP之Content-Length
    关于spring3中No Session found for current thread!and Transaction的配置和管理(转)
    Java数据类型和MySql数据类型对应一览
    Spring MVC 解读——View,ViewResolver(转)
    LeetCode 441. Arranging Coins
    LeetCode 415. Add Strings
    LeetCode 400. Nth Digit
    LeetCode 367. Valid Perfect Square
    LeetCode 326. Power of Three
  • 原文地址:https://www.cnblogs.com/bubu99/p/14095738.html
Copyright © 2011-2022 走看看