zoukankan      html  css  js  c++  java
  • python 学习笔记

    python学习笔记  留作记录

    Python 笔记
    操作命令符:
    cd 打开指定路径
    
    2.dir 浏览目录
    3.mkdir 创建新目录
    4.rmdir 删除目录
    5.Ipconfi 查看 ip
    6.Ping 测试网络连接
    
    > python
    > 计入 python 环境 写 python 程序
    >
    > > exit() 退出环境
    
    > pip list 列出匹配管理包列表
    > pip install <name> 安装包
    > pip uninstall <name> 卸载包
    > pip -V 查看版本
    > pip freeze > requirements.txt 将项目依赖的包输出到指定的 requirements.txt
    > pip install -r requirements.txt   使用 Pip 安装 requirements.txt 中所包含的依赖包
    
    1.Runtime error 缺失程序 python windows 少了补丁
    2.Python 环境变量 3.升级 pip python -m pip install --upgrade pip
    
    进入环境:
    终端输入:
    Python:写 python 代码
    python 源文件:xxx.py 拓展名是 py
    
    交互式 和 源文件
    
    单词:
    Print()打印
    Define(define)定义
    syntaxError 语法错误
    nameError 名字错误
    Invaild 无效的
    Character 字符
    file 文件
    Directory 文件夹
    
    变量替换字符串实例方法:
    
    print(value...,sep='',end='
    '):输出
    sep= 默认间隔字符' '
    end= 末尾默认字符'/n'
    
    '''
    %d 等等等
    %s 等等等
    %f 等等等
    ''' %(arg1,arg2,arg3)
    
    '{}等等等等等等{}等等等'.format(arg1,arg2)
    
    类型转换:
    int——str
    Str——int
    
    imput() 输入:阻塞式
    Name = input('提示语')
    str in str 字符串是否在另一个字符串里面
    str not in str 字符串是否不在另一个字符串里面
    id()返回传入参数的内存地址编码
    is()对比两个对象的是否完全相同
    
    运算符种类:
    赋值运算符 =
    算数运算符 + - * /
    关系运算符 < > <= >= == !=
    逻辑运算符 and or not
    位运算符
    
    python 对小整数的定义是[-5,256](包括基本字母字符)对这些整数对象是提前建立好相应的内存编码,当内容数值是相同的时,都是使用的同一个内存地址,以避免频繁注册及销毁;
    在源文件中 内容相同的数据是直接使用同一个内存地址(不论大小)
    在 python 解释器中超出指定范围的数字及字符则会重新注册创建
    
    bin(num) 将十进制转换为 2 进制
    
    三目运算符
    (当结果为 true 时) if(a>b) else (当结果为 false 时)
    
    逻辑判断:
    if():
    xxx
    elif():
    xxx
    else:
    xxx
    
    random 随机数:
    import random
    random.randint(start,end)
    
    单词:
    help 帮助
    function 函数
    built-in(builtins)内置
    Module 模块
    Value 值
    Stream 流
    Default 默认的
    Format 格式化
    digit 数字 %d
    Required 必须 需要
    Raise 抛出 扔出
    Operator 运算符
    identity 特征 身份
    
    循环语法:
    for 变量名 in 集合:
    语句
    
    range(start,end,num) 获取指定范围内的数值,第三个参数为间隔范围,默认为 0 开始,含头不含末尾的值
    
    pass 补全语句的占位符,防止逻辑结构不全报错
    
    break 终止循环语句
    
    单词:
    Convert 转换 转变
    During 在...期间(之间)
    Range 范围
    integer 整型
    Sequence 序列 队列
    include 包含
    Exclude 不包含
    
    字符串内置方法
    len(str) 返回 str 的字符串长度 length
    str.upper() 字符串大写
    str.lower() 字符串小写
    str.find('str',start ,end) 字符串查找方法 当找到时返回字符串 index 没找到返回-1
    str.rfind()
    str.lfind()
    str.index()
    str.rindex()
    str.lindex()
    str.replace('old','new',num) 字符串替换方法 查找并替换字符串中的内容,num 为替换的次数
    
    编码 解码
    str.encode('utf-8') 将内容编码
    code.decode('utf-8') 将内容解码
    返回值都是布尔类型 True Flase
    str.startswith() 判断 str 是否以 xxx 开头
    str.endswith() 判断 str 是否以 xxx 结尾
    
    str.isalpha() 判断是否是字母
    str.isdigit() 判断是否是数字
    
    ''.join(ArrList) 将符号插入队列中,主要功能将数组转换为字符串
    
    str.strip() 去除前后指定字符串
    str.lstrip() 去除字符串左侧指定字符
    str.rstrip() 去除字符串右侧指定字符
    
    str.split('') 将字符串切割指定字符,并返回新数组
    str.count('') 求字符串中指定的 args 的个数
    
    str in strAll 判断一个字符串里是否包含另一个字符串
    
    del arr[i] 删除数组中的某一项
    
    json.dumps() 将数据转换为 json 字符串
    json.loads() 将 json 字符串还原
    
    max([arr]) 最大值
    min([arr]) 最小值
    
    sorted(list,reverse = True) 排序
    list(string) 将字符串转换为列表
    
    列表添加:
    [].append() 末尾追加
    [].insert() 指定位置插入
    [].extend() 一次添加多个元素
    列表删除:
    del list[i]
    remove()
    pop()
    clear()
    列表排序:
    list.sort() sorted(list) 升序排序
    list.reverse() 降序排序
    list[::-1] 列表取反
    
    enumerate():函数用于将一个可遍历数据对象(如列表、元组、字符串)组合为一个索引序列
    for index,value in list:
    print(index,value)
    
    列表总结:
    list:
    
    - 合并 []+[]
    
    * []*n
    
    in 数据 a 是否在列表 b 中
    not in
    is 内存地址是否相同
    not is
    
    max()
    min()
    
    enumerate 枚举 index value in enumerate(list):
    
    元组
    ()不可修改
    tuple()将元素转换为元组类型 +
    *
    is not
    in not in
    max()
    min()
    sum()
    len()
    sorted()
    a,*b,c=[arr,2,3,3,4,4] *表示未知个数的元素 在解构赋值中获取多余的元素
    
    字典:dictionary
    dict = {} 与对象使用方法差不多,其 key 值用引号括起
    obj = {
    'name':'heihe',
    'age':22
    }
    添加元素(key:value):
    dict[key] = value --->{key:value}
    特点:key 在字典中是唯一的
    
    字典里的函数:items() values() keys()
    
    # for key, value in dist.items():
    
    # if value >= 80:
    
    # print(key)
    
    items 方法调用时可以加入 key,value 将键值对遍历出来,如果只有一个参数那么就会将字典的键值对转成列表保存的形式[(key,value),(key,value)]
    
    dict.get('value',default) 用 get 获取字典中的 value 值 如果不存在则默认返回 None 默认值可修改
    
    删除
    del dict['key']
    dict.pop('key',default) 用 pop 删除指定的键值对 如果不存在则返回默认值
    dict.popitem() 从末尾删除键值对
    dict.clear 清空字典所有内容
    dict.update() 将多个字典合并 //Objcet.assign
    dict.fromkeys(Array, default) 将列表转换为字典,第二个参数 Value 的默认值
    
    集合---无序不重复的序列
    声明集合:set
    
    setlist.add(any) 给集合无序添加元素 将添加的元素以一个整体加入集合中
    setlist.update() 将添加的元素 结构为零散元素添加入集合中
    setlist.remove('key') 删除指定元素
    setlist.pop() 在集合中 pop 删除第一个元素
    setlist.clear() 清空
    
    setlist.discard(num) 删除指定元素,当元素不存在是不会报错
    == 判断两个集合是否相等 判断的是集合中的 value
    
    - 或者 difference() 集合可以用减号求取差集
      & 或者 intersction() 求取集合的交集
      | 或者 union() 求取集合的并集
      ^ 或者 symmetric_difference() 求取集合的不同元素
    
    可变和不可变的
    不可变类型: int str float 元组 tuple
    可变类型:list 列表 set 集合 dict 字典
    
    isinstance(obj,type) 判断传入的 obj 类型是否是 type
    
    可变和不可变:
    list set dict 三个为可变(内容可变,其内存地址不变)
    str int float tuple frozenset 为不可变(内容不可变,其内存地址会变化)
    
    类型转换:
    str-->list set ...相互转换
    list --> set tuple dict 相互转换
    
    函数:
    增加代码复用性,减少代码的冗余
    
    def FunctionName(argumens):
    FunctionBody
    
    argumens 形参列表
    可谓*arg:为传入参数数目不可定;
    (arg1,*arg):arg1 为参数 1,其后身下的参数为*arg (注意,可变参数必须放在固定参数的后边) **传入为元组**
    (arg1,arg2,arg3) 如果要忽略参数 arg2,直接给 arg3 赋值,需要是用关键字进行赋值(1,arg3=10)
    (**args) **两颗星+argumentsName 关键字赋值参数,可以传入随意个数的参数,在调用时需要使用键值对,在函数内部接受结果为字典类型
    FunctionName(**dict) 在调用函数时 使用**双信号字典时,系统会自动将传入参数解构至单元键值对自动传入对应函数中**传入为字典**
    def getMessage(**args):
    print(args)
    dict1 = {'name':'卧槽','age':888,'hoppy':'smoke'}
    getMessage(**dict1)
    
    当传入实参*list[] 列表前加*号时,将列表拆成单个参数传入函数中
    
    函数内部修改全局参数时 全局参数为可变参数时(list、set、dict)直接调用参数(str、int、float、tuple)时需要在名前加上描述:global 之后才可进行全局修改
    
    内部函数调用修改外层函数的变量时 需要与内部函数区分 加上描述:nonlocal 之后才能修改
    
    a= 100
    def func():
    b = 200
    def inner_func():
    nonlocal b
    global a
    c= 300
    b+=1
    a+=2
    print(a,b,c)
    inner_func()
    func()
    //102 201 300
    
    locals()查看本地变量有哪些,以字典形式输出
    golbals() 查看全局变量有哪些,以字典形式输出(包含系统自带键值对)
    
    闭包:
    外层函数返回内层函数(内层函数不调用),内存函数返回被保护的变量
    在全局调用外层函数
    
    def func():
    a = 0
    def inner_func():
    nonlocal a
    a+=1
    return a
    return inner_func
    
    x = func()
    print(x())
    print(x())
    
    装饰器:
    @decorate
    def house():
    pass
    
    1.house 被装饰函数 2.被装饰函数作为参数传入装饰器 decorate 3.执行 decorate 函数 4.将返回值赋值给 house
    
    双层装饰器:
    @deracotor2
    @deracotor1
    def house(*arg,**kwargs):
    print('这是一个 base house')
    
        双层装饰器调用时,谁离装饰函数越近就越先被调用
    
    装饰器带参数
    带参数的装饰器是三层的
    最外层的函数负责接收装饰器参数
    里面的内 ring 还是原装装饰器的内容
    
    函数作用域:
    LEGB
    L:local 本地
    E:encloseing 嵌套
    G:global 全局
    B:built-in 内置的
    
    匿名函数: lambda
    
    内置函数: 在大多数情况下 结合 lambda 使用内置函数 效果最佳
    max list(max(list1,lambda key=x:x['a']))
    map list(map(lambda x:x+1,list1))
    reduce list(reduce(lambda x,y:x+y,list1)) from functools import reduce 该函数需要单独引用
    filter list(filter(lambda x: x>3,list2))
    sorted list(sorted(list1,key=lambda x: x['b']))
    
        文件操作:
        file=>文件路径
        mode=>r(rt读入文本),w(wt写入文本),rb(读入二进制),wb(写入二进制),a(append 写入内容为追加,不会重置写入内容)
        buffer=>所占内存
        open(file,mode,buffer)
            读取:
            stream = open('test.txt',encoding='utf-8')
            stream.read() 从流中将文件内容读取出,该目录下其他操作符无效
            stream.readline()  读取一行 每打印一次行数+1
            stream.readlines() 读取全部内容
            stream.readable() 查看文件是否可读取
            mode ='rb' 读取内容格式为2进制 (当文件类型不是默认文本类型时,修改参数mode为'rb')
    
            写入:
            stream = open('test.txt',mode='w',encoding='utf-8')
            stream.writable()是否可写入
            stream.write() 写入相应的内容(每次进行写入操作时都会先将内容清空)
            stream.writelines('[]') 写入一行的内容(写入的内容以列表形式写入)
    
            追加:
            mode = 'a'
            写入的内容不会被重置
    
    OS 模块 (operating system)
    
    os.path.dirname(**file**) 查询当前页面所在文件夹
    
    os.path.join(path,'filename' ) 根据参数中的路径 拼接文件名
    
    path = os.path.abspath('test.txt') 查询指定文件的绝对路径
    path = os.path.abspath(**file**) 查询当前文件所在绝对路径
    
    os.path.isfile('name') 判断是否是文件
    os.path.isdir('name') 判断是否是文件夹
    
    os.path.split(path) 切割路径 获得文件名
    os.path.splitext(path) 切割路径 获得拓展名(可用来判断文件类型)
    
    os.path.size(name) 返回文件的大小
    
    os.getcwd() 获取当前目录
    os.listdir('hehe') 浏览文件夹
    os.mkdir('name') 新建文件夹
    os.removedirs('name') 删除文件夹
    os.remove('name')删除文件
    os.chdir('name') 切换文件路径
    
    异常处理:
    try: 可能出现错误的代码
    except Exception as e: 如果有异常执行的代码
    finally: 无论是否存在异常都要执行的代码
    
    列表推导式:
    [i for i in list] or [i for i in list if i 条件]
    
    定义生成器方法 generator: 1.通过列表推到方式
    g = (x*3 for x in range(10))
    调用 g.**next**() 时,将自动生成下一个对应的数值,从而减少内存的使用 2.函数+yield
    步骤: 1.定义一个函数,函数中使用 yield 关键字 2.调用函数,接受调用的结果 3.得到的结果就是生成器 4.借助 next() **next**() 得到元素
    
    def func():
    n = 0
    while True:
    n += 1
    yield n
    g = func()
    print(next(g))
    print(g.**next**())
    
    **next**():获取下一个元素
    next(generator):每次调用都会产生一个新的元素,如果元素产生完毕,再次调用会抛出错误
    sent(value):向每次生成器调用中传值 注意:第一次调用 send(None)
    
    # 斐波拉契数列 生成器方法
    
    def fib(num):
    a, b = 0, 1
    n = 0
    while n < num:
    g = yield b
    if g:
    print(str(g)+'..wocao')
    a, b = b, a+b
    n += 1
    return 'none'
    
    g = fib(10)
    for i in g:
    if(i % 2 == 0):
    g.send(i)
    
    迭代是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个冤死开始访问,直到所有的元素被访问完结束,迭代器只能往前不会后退。
    可以被 next()函数调用并不断返回下一个值的对象称为迭代器:Iterator.(生成器是可迭代的,也是迭代器,list 是可迭代的,但不是迭代器)
    
    iter(iterator) 将可迭代变为迭代器
    
    类方法:
    特点: 1.定义需要依赖装饰器@classmethod 2.类方法中的参数不是一个对象,而是类本身 3.类方法中只可以使用类属性 4.类方法中不可使用普通方法 5.类方法中可同步调用类方法 6.类方法是不依赖对象的,类方法是在普通方法前初始化 7.普通方法可以用类名.方法名全局调用类方法
    类方法的作用:
    因为类方法只能访问类属性和类方法,所以可以在对象创建之前需要完成一些动作(功能)
    
    class 类的使用
    \_\_name 加下划线的属性为私有属性,只可在内部调用
    
    静态方法:很类似类方法 1.需要装饰器 staticmethod 2.静态方法无需传递参数<cls,self> 3.也只能访问类的属性和方法,对象的是无法访问的 4.加载时机同类方法
    总结:
    类方法 静态方法
    不同: 1.装饰器不同 2.类方法是有参数的,静态方法没有参数
    相同: 1.只能访问类的属性和方法,对象的是无法访问的 2.都可以通过类名进行调用访问 3.都可以在创建对象之前使用,因为是不依赖于对象、
    
    普通方法 与两者的区别:
    不同: 1.没有装饰器的 2.普通方法依赖对象,因为每一个普通方法都有一个 self 3.只有创建了对象才可以调用普通方法,否则是无法调用的。
    
    #魔术方法
    **init**:初始化魔术方法
    触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
    
        __new__:实例化的魔术方法
        触发时机:在实例化时触发
        作用:开辟内存空间
    
        __call__:对象调用方法
        触发时机:将对象当成函数使用的时候 会默认调用此函数中的内容
    
        __del__:析构魔法方法
        触发时机:当对象没有用(没有任何变量引用)的时候触发
        def obj  删除obj地址的引用
                 当一个空间没有了任何的引用时,将会默认执行__del__
                 ref失灵 是因为该目标没有任何引用
        __str__:打印对象名 自动触发去调用__str__里的内容  注意:需要return 返回
        单词打印对象是返回的是一个内存地址,对于开发者来说作用不大,如果想打印对象名的时候能够给开发者更多一些信息量使用__str__。
    
    sys.getrefcount() 查询调用目标内存被引用的个数(本次查询也被记录在结果中)
    
    魔术方法重点:**init** (构造方法,创建空间后的第一个调用 ) **str**
    了解:**new** 自定义开辟空间时的设置(80%不需要重写) **del** 没有引用时会自动调用重写(99%不需要重写) **call** 想不想将对象当函数调用
    
    大总结:
    普通方法
    def 方法名(self,[参数]):
    pass
    对象.方法()
    
    类方法 @classmethod
    def 方法名(cls,[参数]):
    pass
    类名.方法()
    对象.方法()
    静态方法 @staticmethod
    def 方法名([参数]):
    pass
    类名.方法()
    对象.方法()
    魔术方法
    
    私有化:(demo0313.py)
    封装:1.私有化属性 2.定义共有 set 和 get 方法
    \_\_属性:就是讲属性私有话
    好处:1.隐藏的私有化属性不被外界随意修改 2.也可以修改,通过函数
    def setXXX(self,xxx): 3.筛选赋值的内容
    if xxx 就否符合相应的条件
    赋值
    else:
    不赋值 3.如果想获取具体的某个属性 使用 get 函数
    def getXXX(self,xxx):
    reutnr xxx
    
    通过 dir(Person) 可查看文件所有的属性,其中包括私有属性内容,其实他是的私有属性通过系统进行自动改名
    
    @property 私有属性装饰器
    def xxx(self):
    pass
    用@property 装饰器修饰私有变量 xxx
    
    @xxx.setter
    def xxx(self,new):
    self.xxx=new
    
    用属性 xxx.setter 作为装饰器 修饰私有变量的修改方法
    
    知识点:
    1.has a 一个类中 使用了另外一种自定义类型
    student 使用了 computer book
    2.is a
    类型:
    系统类型:
    str int float list dict tuple set
    自定义类型:
    class 算是自定义的类 都可以将其当成一种类型
    s = Student() s 是 Student 类型的对象
    
    继承:(demo0313.py)
    Doctor,Worker,Police 都属于人类 Person
    相同的代码 代码冗余,可读性不高
    
    将相同代码提取->Person
    Doctor,Worker,Police ->都继承 Person
    
    super()表示父类对象
    特点:(demo0314.py) 1.如果类中不定义**init**,调用父类 super class 的**init**(params) 2.如果类继承父类也需要定义自己的**init**,就需要在当前类型的**init**调用一下父类的**init** 3.如何调用父类的**init**:
    super().**init**(参数)
    super(type,对象).**init**(参数) 4.如果父类有 eat(),子类也定义一个 eat 方法,默认搜索的原则:先找到当前类,再去找父类
    s.eat()
    override:重写(覆盖)
    父类提供的方法不能满足子类的需要,就需要定义一个同名的方法,这个行为就称为:重写 5.子类的方法也可以调用父类方法:
    super().方法名(参数)
    
    import inspect
    inspect.getmro(Class) 或者 Class.**mro** 查询类属性的调用层级关系
    
    python 允许多继承,调用原则为广度优先
    def 子类(父类 1,父类 2):
    pass
    
    总结:
    
    私有化:封装 将属性私有化,定义公有化 set 和 get 方法
    def setAge(self,age):
    判断
    def getAge(self):
    return self.\_\_self
    
    s.setAge(20)
    s.getAge()
    
    class Student:
    def **init**(self,age):
    self.**age = age
    @property
    def age(self):
    return **age
    
    @age.setter
    def age(self,new)
    self.\_\_age = new
    
    s = Student(20)
    s.age(30) 设置私有属性 AGE
    s.age() 获取私有属性 AGE
    
    继承:
    has a 包含继承
    class Student:
    def **init**(self,name,book): //name book 都为实例化类  
     pass
    is a 继承
    正常类的继承方法
    
    python 的多态是类似于多态的方式,用 isinstance 进行判断
    isinstance(obj,类) 判断 obj 是不是这个类 或者是这个类的子类
    
    多态:简单来说就是允许子类类型的指针赋值给父类类型的指针
    
    单例:
    自定义控制内存空间的创建,从而减少内存的使用
    class Person:
    \_\_that = None
    
        def __new__(cls):
            if cls.__that == None:
                cls.__that = object.__new__(cls)
                return cls.__that
            else:
                return cls.__that
        p = Person()
        p1 = Person()
    
    1.自定义模块 2.使用系统一些模块
    
    导入模块:
    1.import 模块名
    模块名.变量 模块名.函数 模块名.类
    2.from 模块名 Import 变量|函数|类
    3 from 模块 import *  
     引入该模块中所有的内容,但是如果想限制获取的内容**all**=['允许被导出的模块'] 4.无论是 import 还是 from 的形式,都会讲模块内容进行加载,如果不希望其进行调用,就会用**name**
    在自己的模块里面**name**叫:**main**
    如果在其他模块中通过导入的方式调用的话:**name**:模块名(在其他模块引入原模块时,**name**值为原模块名字,在原模块中调用时
    **name**值为'**main**')
    
    文件 包 (demo0318.py)
    非 py 文件 包:py 文件
    一个包中可以存放多个模块
    项目>包>模块>类 函数 变量
    
    from 包 import 模块
    from 包.模块 import 类|函数|变量
    from 包.模块 import * (**all** = [])
    
    **init**.py 文件
    当导入包的时候,默认调用**init**.py 文件
    作用: 1.当导入包的时候,把一些初始化的函数,变量,类定义在**init**.py 文件中 2.此文件中函数,变量等的访问,只需要通过包名,函数... 3.结合**all** = [通过*可以访问的模块]
    
    import _ 表示可以使用模块里的所有内容,如果没有定义**all**所有的都可以访问
    但是如果添加上了**all**,只有**all** = [''] 列表中可以访问
    from user import _ 表示该包中内容(模块)是不能访问的,就需要在**init**.py 文件中定义**all** = [可通过*访问的模块]
    
    循环导入:大型的 python 项目中,需要很多 python 文件,由于架构不当, 可能会出现模块之间相互导入
    A:模块
    def test():
    f()
    B:模块
    def f():
    test()
    避免产生循环导入: 1.重新架构 2.将导入的语句放在函数里面 3.把导入的语句放在模块最后
    
    sys.argv 查看启动 Python 程序时 附带的参数
    
    time 模块:
    time.time() 获取时间戳
    time.sleep(2) 延时
    time.ctime(t1) 将时间戳转为为时间格式
    time.localtime(t) 将时间戳格式化为元组,可从中获取对应的时间信息
    time.mktime(t) 将格式化 localtime 时间转化为时间戳
    time.strftime('%Y-%m-%d %S:%M') 将元组的时间格式化成指定样式
    time.strptime('2020/03/19 15:59', '%Y/%m/%d %S:%M') 字母转换成元组的方式
    
    datetime 模块:  
     time 时间
    date 日期 (date 数据)
    datetime 日期时间 new()当前时间 str
    timedalte 时间差 timedalta(days="",week="",hour="",...)
    
    random 模块:
    random.random() 0-1 之间小数
    random.randint(a,b) a-b 之间的数字
    random.randrange(start,end,step) 从 start 开始产生 end 随机数,以 step 为步长
    random.choice([list]) 随机返回 List 列表内的元素
    random.shuffle(list1) 打乱 list 列表内的数据顺序(修改原数组)
    chr(random.randint(65, 90)) chr 将传入的数字转换为字母
    ord('A') ord 将传入的内容转为 Unicode 码
    
    hashlib 模块:(demo0320.py)
    hashlib.md5(msg.encode('utf-8')) 将 Msg 编译成 md5
    hashlib.sha1(msg.encode('utf-8')) 将 Msg 编译成 sha1
    
    查看:
    sha1 = hashlib.sha1(msg)
    print(sha1.digest()) 查看编码
    print(sha1.hexdigest()) 查看 16 进制编码
    
    re 正则(demo0324.py)
    re.match(reg,str) 进行正则字符串匹配第一次出现的结果
    re.search()
    re.findAll(reg,str) 进行正则全局匹配所有结果
    re.sub(pattern,'新内容',string) 将匹配的数据进行替换
    re.split(pattern,string ) 将符合的字符串位置切割成数组 result = re.split(r'[,:]', s3)
    [a-z] 在正则中[]表示在括号中的任一数字
    
    ^开头
    $结尾
    [] 范围
    
    - 表示匹配 0 或者 0 以上(贪婪) >=0
    
    * 表示匹配 1 或者 1 以上(贪婪) >=1
      ? 表示匹配 0 或者 1 次(贪婪) 1,0
      *? +? ?? 非贪婪模式
      /s 空白
      /b 边界
      /d 数字
      /w word 字母
      (word|word|word) 区别 [163]表示是一个字母而不是一个单词
      {start,end} 表示匹配次数的范围
      在字符串之前加上 r'xxxx' 该字符串将不会发生转译
    
    通过匹配正则中的小括号进行分组,使用 group(1) 获取分组数据
    phone = '023-8848123'
    result = re.match(r'(d{3}|d{4})-(d{2,8})$', phone)
    print(result.group(1))
    print(result.group(2))
    
    s1 = '<html><head>hehehe</head></html>'
    s2 = '<h1>ABC</h1>'
    result = re.match(r'<[0-9a-zA-Z]+>(.+)</[0-9a-zA-Z]+>$', s1)
    print(result.group(1))
    
    使用 (?P<名字>w+) (?P=name) 为后期直接调用名字
    
    进程与线程 (demo0325.py)
    并发:当有多个线程在操作时,如果系统只有一个 CPU,则它根本不可能真正同时进行一个以上的线程,它只能把 CPU 运行的时间划分成若干个时间 段,在将时间段分配个各个线程执行,在一个时间段的线程代码运行时,其他线程处于挂起壮,
    这种方式我们称之为并发(Concurrent)
    并行:当系统有一个以上 CPU 时,则线程的操作有可能非并发。当一个 CPU 执行一个线程时,另一个 CPU 可以执行另一个线程,两个线程互不抢占 CPU 资源,可以同时进行,这种方式称之为并行。
    多进程模式:
    多线程模式:
    协程:
    进程>线程>协程
    
    查看线程信息
    import os  
    os.getpid()查看子线程 id
    os.getppid()查看主进程 id
    
    from multiprocessing import Process
    
    Process(target=函数,name= 进程的名字,args=(给函数传入的参数)
    process 对象
    自定义进程方法:
    class myProcess(Process):
    def run (self):
    
    p = myProcess()
    p.start()
    
    对象调用方法:
    process.start() 启动进程 并执行任务
    process.run()只是执行任务 但是没启动进程、
    terminate() 终止
    
    当需要创建的子进程数量不多时,可以直接利用 multiprocessing 中的 Process 动态生成多个进程,
    但是如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此事就可以用到 multiprocessing 模块提供的 Pool 方法,
    初始化 Pool 时,可以指定一个最大进程数,当有新的请求提交到 Pool 中时,如果池还没满,
    那么就会创建一个新的进程用来执行该请求:但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,
    知道池中有进程结束,才会创建新的进程来执行。
    
    poo = Pool(number) 创建进程池对象
    初始 Pool(number) 时,新开启的进程将创建对应 number 数量的进程数进行交替使用
    
    非阻塞式进程: 全部添加到队列中,按顺序进栈,执行完毕后立刻返回,直到队列清空 使用 pool.apply_async(func,args,callback)
    阻塞式进程: 逐个调用队列中的线程,完成一个调用一个,没有返回值,知道队列清空 使用 pll.apply(func,args)
    
    pool.close() 关闭
    pool.join() 插队,让主进程让步,进行子进程的调用
    
    队列方法(demo0326.py)
    q = Queue(6)
    q.full() 判断队列是否已满
    q.empty() 判断队列是否已空
    q.put(item) 推入队列
    q.get() 获取队列数据
    
    q.put_nowait() 不等待方法
    q.get_nowait()
    
    线程:有时被称为轻量进程,是程序执行流的最小单位。
    多线程:是指从软件或硬件上实现懂个线程并发执行的技术。
    
    t = threading.Thread(target=func,name = '',args = (a,))
    t.start()
    线程时可以共享全局变量的
    Python 底层只要用线程默认加锁:
    GIL 全局解释器锁
    当线程异步处理统一数据是回出现数据不安全的情况,导致取得的数据出现问题
    解决办法:线程同步,速度慢,数据安全
    
    线程:适合耗时操作,爬虫,IO
    进程:适合计算密集型
    
    线程同步方法(demo0330.py)
    from threading import Lock
    l = Lock() 线程锁模块
    l.acquire() 线程加锁 阻塞
    l.release() 线程锁释放
    
    数据共享
    进程共享数据与线程共享数据区别:
    进程是每个进程中都有一份数据
    线程时所有并发线程公用一份数据 ==>数据安全性问题
    GIL->伪线程  
     使用 Lock 模块添加及解除同步进程锁 lock.acquire() lock.release()
    当使用加锁顺序不当时将出现死锁, 需避免死锁 timeout = number 或代码重构
    线程间通信:生产者与消费者
    生产者是一个线程
    消费者也是一个线程
    improt Queue
    q = queue.Queue()
    
    协程:微线程
    进程>线程>协程
    Process > Thread > 生成器完成
    
    greenlet 手动协程模块
    gevent 自动协程模块
    
    gr = greenlet(func)
    gr.switch() 指定下一个切换的函数
    
    g = gevent.spawn(func,args)
    g.join()
    monkey 猴子补丁 from gevent import monkey monkey.patch_all() 将程序中用到的耗时操作的代码,换为gevent中自己实现的模块
    '
    '
  • 相关阅读:
    微信公众平台回复音乐
    Else is very important
    Generate source code from wsdl
    PHP Simple HTML DOM Parser: check elements with multiple classes
    Get Version is the first function is called?
    Remote debug GWT UI
    Remote Debug For Java Application On Tomcat
    SetStyleName引起的Regression Issue
    做乘法运算的时候需要考虑越界问题
    MySQL Uniall All
  • 原文地址:https://www.cnblogs.com/bomdeyada/p/12606972.html
Copyright © 2011-2022 走看看