python基础

关键常识点

  1. Python的意思是蟒蛇
  2. Python的作者是Guido van Rossum
  3. Python正式诞生于1991年
  4. Python是shell语言和c语言结合一起开发的一种语言

Python应用场景

web应用开发

操作系统管理、服务器运维的自动化脚本

科学计算机器学习

服务器软件

关键字和标识符

1.标识符由下划线、字母和数字组成,且数字不能开头

2.python中标识符区分大小写如:Anad!=anad

3.驼峰命名法

4.通过keyword kwlist查看系统中的关键字

python中的运算符

/:除

//:取整除

**:表示阶乘

and、or、not:表示逻辑运算符中的与、或、非

python中的函数在ipython中查看帮助文档

print()中是带有默认的换行符的,要想它不带换行符就用print(“values……”,end="")

语法知识

基本数据类型

  1. 数字(num)
    1. int
    2. float
    3. complex(复数)
    4. bool(布尔)
  2. 字符串
  3. 字典(dict) { }
  4. 元组(tuple)()
  5. 列表(list) [ ]

不可变类型


1.值可以修改(内存地址不变但是保存的值变化了),引用可以修改(变量的内存地址变化了)

2.对于不可变类型对于调用的函数,一般不改变原数据,只是返回一个新的同类型的数据。

3.“=”是赋值符号,通过等号来改变变量,属于改变该变量的引用

类别:数值、字符串、元组

可变类型


1.值不可以修改,引用可以修改(变量的内存地址变化了)

2.对于可变类型来说,a=a+某数据 和a+=某数据最终的操作结果是不同的,前者表示修改引用,后者表示修改引用的值,但是对于不可变类型来说是一样的,都是改变变量的引用

3.“=”是赋值符号,通过等号来改变变量,属于改变该变量的值

类别:list,dict

bool类型值的注意事项

的值False和True的首字母要大写,否则会报错

while和for循环的格式:

​ for 临时变量 in 列表或者字符串:

​ 循环时执行的代码

​ else(可以省略):

​ 循环不满足条件时执行的代码(如果之前遇到break的话,也会跳过该else)

​ while 条件表达式:

​ 循环体

​ else(可以省略):

​ 循环体

切片(包头不包尾)

格式是:[起始下标:结束下标:步长]

从左往右是从0开始,从右往左是从-1开始

实现字符串的倒叙:

name=“adfdsdfdjl”

name[-1::-1]


字符串常见的操作函数

查找函数

find函数默认从左边开始查找

用法实例:mystr.find(str,start,end=(mystr))表示检验str是否包含在mystr中,如果包含在其中就返回str开始的索引值,如果没有查找到就返回一个值-1

rfind函数默认从右边开始查找

用法跟find差不多

indexof函数

跟find一样,就是如果查找不到就会报错

rindexof函数

跟indexof一样

count函数

用法实例:mystr.count(str1,start=0,end=len(mystr))表示查找str1在mystr中出现的个数并返回这个数值。

endwith函数

用法实例:mystr.endwith(str):表示查找mystr是否是以str结尾的,是则返回一个true,不是则返回false,常常用于查看文件的类型

starwith函数

用法跟endwith函数一样

替换函数

replace函数

用法实例:mystr.replace(str1,str2,count(str1))把mystr中的str1替换成为str2,如果count指定,则替换不超过count次

upper函数

用法实例:mystr.upper():表示用大写字母替换mystr中的小写字母,常常用于在用户输入过程中实现不区分大小写

lowe函数

用法跟upper函数刚刚好相反

join函数

用法实例:mystr.join(list)表示以mystr作为分隔符将list的每个元素连接成为一个字符串

分割函数

split函数

用法实例:mystr.split(str):表示以str作为分隔符进行分割mystr字符串,返回一个字符串的列表(它把分隔符给去掉了,返回的列表中不包含分隔符)

partition函数

用法跟split函数一样,只是返回的列表中是包含分隔符的

布局函数

ljust函数

用法实例:mystr.ljust(width)表示返回一个原字符串左对齐,并使用空格填充至长度width的新字符串

rjust函数

用法跟ljust函数一样

center函数

用法跟ljust函数一样

ltrip函数

用法实例:mystr.ltrip()表示去掉字符串mystr左边的空格

rtrip函数

用法跟ltrip函数是一样的,去掉右边的空格

strip函数

用法跟ltrip函数一样,它是去掉两边的空格

元组与列表

  1. 元组和列表都是有序的集合

  2. 元组(tuple)用(),与列表(list)用[ ]

  3. 主要区别是元组是不支持赋值的,也就是只能读取不能改写,但是我们可以通过把元组中要修改的元素类型设置为列表进行修改,其他的语法跟列表一样

  4. 元组和列表是可以相互嵌套的

  5. 枚举函数enumerate多用于在for循环中得到计数,利用它可以同时获得索引和值,元组列表都适用,举例如下:

    >>> lst = [1,2,3,4,5,6]
    >>> for index,value in enumerate(lst):
      print ('%s,%s' % (index,value))
      
    0,1
    1,2
    2,3
    3,4
    4,5
    5,66
    

6.set集合的元素是不可以重复的,如果要去除列表中的重复元素可以将list集合先转换为set集合再转换为list集合

字典(dict用{ })

跟java中的map是一样的,其中key是不可以重复的

字典(dict)用{ }

字典的增、删、改、查:

:字典名字[“key”]=值

:del 字典名字[“key”],只需要删除其中的key

:字典名字[“key”]=新的值

:字典名字[“key”],字典名字.get(“key”),可以用in进行访问,但是查找的是key

字典中常用的函数

  1. 字典转换为列表(键值对作为函数的元素)处理用iterm()函数例如:
nums={"name:":"laowang","age":"19"}

nums.items()得到的是:

**dict_items([('name:', 'laowang'), ('age', '19')])

**

  1. a=(11,22);c,d=a的效果是c=11,d=12,相当于拆包赋值的方法,在遍历中还能这样用:
for a,b in nums.items():

​    print("%s,%s"%(a,b))

打印出来的就是:下面的样子

name:,laowang

age,19
  1. 字典的排序

    sorted(dict.items(),key=lambda d:d[1])
    其中dict为字典,d为随意取的变量名用来代替前面得到的每一项,0就是按照key排,1就是按照值排
    

字典、元组和列表的公用的工具

运算符

+:合并

*:复制

in:存在

not in:不存在

内置函数

数学运算

cmp(item1,item2):比较两个值的大小

round(x,y):四舍五入取值,x为要取值的数,y为保留的小数点位数

abs(x):取x的绝对值

pow(x,y):求x的y次方

len(item):计算容器中元素的个数

max(item):返回容器(可以是多个数,也可以是元组或者列表)中元素的最大值

min(item):返回容器中元素的最大值

del:删除元素

eval():执行字符串表达式,如eval(‘1+2+3’),也可以执行定义的函数名字符串,eval(“fun(a,b,c)”)

类型转换

int(),float(),str(),list(),tuple(),dic(),bin()十进制转换成二进制,hex()十进制转换成十六进制,char()数字转换成字符,bytes()转换成字节数组

序列操作函数
  1. all()用来判定可迭代对象参数中是否所有的元素都为TRUE,返回值为bool值True或false,除了是0,空,false外都是true,但空元组空列表返回值都是True

  2. any()用来判定可迭代对象参数中是否存在一个元素为TRUE,返回值为bool值True或false,除了是0,空,false外都是true

  3. sorted()函数对所有可迭代的对象进行排序操作。

    1. sort()和sorted()的区别:sort只应用于list上的方法,sorted()可以对所有可迭代对象排序。list的sort方法返回的是对已经存在的列表进行操作,而sorted返回的是一个新的list
  4. reverse()用于反向列表中的元素

  5. range()创建一个整数列表,一般用在for循环中

  6. zip()将对象中的元素打包成一个个的元组,然后返回这些元组组成的列表

    s1=['a','b','c']
    s2=['你','我','他']
    print(list(zip(s1)))
    [('a',), ('b',), ('c',)]
    print(list(zip(s1,s2)))
    [('a', '你'), ('b', '我'), ('c', '他')]
    
  7. enumerate()将一个可遍历的对象(如列表、元组或者字符串)组合成一个索引序列,同时列出数据和数据下标,一般用于for循环中

    l=['a','b','c','d']
    for index,item in enumerate(l):
        print(index,item)
        
    0 a
    1 b
    2 c
    3 d
    

集合

不支持索引和切片,是一个无序的且不重复的容器,属于可变类型,可以进行增删改,不可以查

set1={1,2,3}
print(type(set1))

函数

1.定义的格式:

​ def 函数名(参数……):

​ 函数体

2.区分定义函数和加载函数的概念,在定义的函数里可以调用下面定义的函数,注意从上往下执行的顺序就好。

3.可变长的参数,使用“*args”或者“**args”来表示,第一个表示元组,它会将所传的参数组成一个元组,第二个表示字典,所传的是字典类型,字典要求带上两个星,或者是传递键值对

#元组示例
def fun(*args):
    print(args)
    
fun((1,2,3,4,5))
((1, 2, 3, 4, 5),)
fun(1,2,3,4,5)
(1, 2, 3, 4, 5)
#字典实例
def fun2(**agrs):
    print(agrs)
    
fun2(**dicta)
{'name': 'xiaoming', 'age': 23}
fun2(name="xioahong",age=19)
{'name': 'xioahong', 'age': 19}

4.函数参数的传递传递的是变量的引用

5.默认参数直接在参数中写等号赋值就好了,如下代码一样。注意含有默认参数的函数,在调用赋值时是按照顺序的。

def fun(a=10,b=20)....
注意不能写成fun(a=10,b)按照顺序,默认参数后面的参数也必须是默认参数

6.简化的if else三元运算符:

if a:
	b
else:
	c
可以简化为
b if a else c
例子:
print('可以参军'if age>18 else '继续上学')

匿名函数


  1. 用lambda关键字声明

  2. 格式为:

    ​ lambda 参数:

    ​ 函数体

    test=lambda a,b:a+b
    相当于
    def test(a,b):
    return a+b
    
  3. 匿名函数可以作为参数传递给非匿名函数

  4. 匿名函数可以用于动态代码

全局变量

  1. 对于可变类型我们可以直接在全局或者局部(如函数)中修改
  2. 对于不可变类型,在函数中在变量之前加上global就可以对全局变量进行修改(严格来说不能叫做修改,应该叫做修改引用)

类和对象

  1. 类:

    1. 定义:
    class 类名(object):
    	属性
    	方法
    
    1. 类属性和实例属性:类属性定义在类里面方法外面的属性称之为类属性,类属性是类所拥有的,能被所有实例对象所共有,相当于java中的static修饰的属性。实例属性定义在方法里面使用self引用的属性称之为实例属性,只能通过实例对象访问。
    class person():
    	name=“小明”		#类属性
    	def __init__(self):
    		self.age=23		#实例属性
    
    1. 常见的魔方方法

      1. __init__(self)方法,是在类实例化对象的时候自动调用,完成一些初始化操作
      2. __str__方法,在将对象转化成字符串测试的时候,打印对象的信息。
      3. __new__方法,创建并返回一个实例对象,调用一次就会得到一个对象,创建对象后必须返回,否则就创建不成功了。new方法的执行要早于init方法。只有继承object的新式类才有这一魔法方法。如果这个函数没有返回实例对象,则不会调用init方法。
      class Person(object):
          def __init__(self):
              self.color='red'
              pass
          # 不重写的情况下默认结构是下列样子
          def __new__(cls, *args, **kwargs):
              # super()表示继承的object类
              return super().__new__(cls,*args,**kwargs)
      
      1. __class__获得已知对象的类
      2. __ del__ 对象在程序运行结束后进行对象的销毁的时候调用这个方法来释放资源
      3. __mro__可以显示类方法的执行顺序。
    2. self和对象指向同一个内存地址,可以认为self就是对象的引用。self就是实例对象的引用。

    3. 类方法和静态方法:

      1. 类方法:是类对象所拥有的方法,需要用装饰器**@classmethod**来标识其为类方法,对于类方法,第一个参数是类对象,一般以cls作为第一个参数,类方法可以通过类对象和实例对象调用。类方法主要可以对类属性进行修改、访问。
      2. 静态方法:是类对象所拥有的方法,需要用**@staticmethod**来表示静态方法,静态方法不需要任何的参数。
    4. 私有属性:两个下划线开头如:__age=19,私有属性不能损益改变,也不能让派生类(子类)去继承。

    5. property对象的类属性:

    class Person:
        def __init__(self):
            self.__age = 18
    
        # 定义一个类属性,实现通过直接访问属性的形式去访问私有的属性
        def get_age(self):
            return self.__age
    
        def set_age(self, age):
            self.__age = age
        # 没有加这个不能通过实例化对象访问私有属性
        age = property(get_age, set_age)
    
    
    p=Person()
    print(p.age)
    p.age=20
    print(p.age)
    
  2. 对象:

    1. 定义:
    对象名=类名(object)
    
  3. 析构方法:当一个对象被删除或者被销毁时,python解释器也会默认调用__del__()这个方法,回收内存资源,这就是析构方法。

  4. 面向对象的三大特征:

    1. 封装:把内容封装到某个地方,便于后面的使用

    2. 继承:子可以继承父的内容**[属性和行为]**,父类又称为基类,子类又称为派生类。

      1. 格式为:
      class 子类名(父类):
      	pass
      
      1. 多继承:Python是可以多继承的,一个子类可以有多个父类。
      2. 调用父类的方法可以使用super()或者父类名调用父类的方法
    3. 多态:定义时的类型和运行时的类型不一样。多态的两个前提

      1. 继承:多态必须发生在子类和父类之间
      2. 重写:子类重写父类的方法

文件操作


文件操作的一般步骤

打开文件

读/写文件

保存文件

关闭文件

打开文件

open(‘文件名称’,‘打开模式’,encoding=“utf-8”)文件打开文件,默认是jbk编码模式

访问模式 说明
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

关闭文件

close()方法关闭,该方法是包含了保存操作的,也就是保存后关闭

读数据

  1. read函数以字节方式读数据,read(参数)中的参数是数字时表示读取的字符数,如果不加参数则默认全部读写出来

  2. readline()读一行数据

  3. readlines()读文件中的所有行数据,返回一个列表对象

  4. tell函数可以显示读取到第几个字节,返回它的下标数

  5. 当文件很大时,我们一般需要对read()函数传递参数,表示一次性读多少字节,所以一般配合循环使用来读取整个文件

    写数据

write(‘待写的数据’)函数

os模块的用法


见:https://www.cnblogs.com/apollo1616/p/9510322.html

  1. os模块提供的是一些系统级别的命令
  2. 常用的方法:

os.listdir(dirname):列出dirname下的目录和文件,例如:for x in os.listdir(os.path.join(folder, name , ‘data’)) if “index” in fn])
os.getcwd():获得当前工作目录,例如:subfolder = os.getcwd().split(‘dirsubname’)[0]
os.curdir:返回当前目录(’.’)
os.chdir(dirname):改变工作目录到dirname
os.path.isdir(name):判断name是不是一个目录,name不是目录就返回false
os.path.isfile(name):判断name是不是一个文件,不存在name也返回false
os.path.exists(name):判断是否存在文件或目录name
os.path.getsize(name):获得文件大小,如果name是目录返回0
os.path.abspath(name):获得绝对路径
os.path.normpath(path):规范path字符串形式
os.path.split(name):分割文件名与目录(事实上,如果你完全使用目录,它也会将最后一个目录作为文件名而分离,同时它不会判断文件或目录是否存在)
os.path.splitext():分离文件名与扩展名
os.path.join(path,name):连接目录与文件名或目录,例如:folder = os.path.join(’…’,‘pose’,‘data’)
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路径

import os,shutil
# os.rename('Test.txt',"Test_重命名.txt")
# os.remove("Test_重命名.txt")
# 创建文件夹,不允许级联创建目录,比如:d:/Python/项目/代码
# os.mkdir("TestCj")
# 创建多级目录
# os.makedirs(目录名)
# 删除文件夹,智能删除空目录
# os.rmdir("TestCj")
# 要删除非空目录,需要另一个模块shutil
# shutil.rmtree(文件名)
# 获取当前目录
# os.getcwd()
# 路径的拼接
# os.path.join(路径一,路径二)
# 遍历文件的列表
# os.listdir(路径)老版的
# os.scandir(路径)新版的
# 新的返回一个迭代器,可以使用with来操作
# with os.scandir("d:/") as entries:
#     for entry in entries:
#         print(entry)

命令行参数

  1. Python可以使用sys模块中的sys.argv来获取命令行参数,常用于开发脚本
#编写Py文件
import sys
print(str(sys.argv))
# 在命令行中输入
(view) E:\solftWores\Python3\romming\练习>python main.py 1 2 3 4 5
['main.py', '1', '2', '3', '4', '5']

  1. argparse模块 ,可以轻松编写用户友好的命令行界面
# 导入包
import argparse

# 创建解析器
ap = argparse.ArgumentParser()
# 添加可选参数(positional arguments)
ap.add_argument("-i", "--input", required=True,
                help="path to the input folder")
ap.add_argument("-m", "--model", required=True,
                help="path to the model file")
# 含有默认值的参数以及限定了值的参数
ap.add_argument("-s", "--sex", required=True,defout='男',choices=['男','女']
                help="path to the model file")
# 添加位置参数(positional arguments)
parse.add_argument("name",type=stre,help="你自己的名字")

args = vars(ap.parse_args())
print(args)
print(args["input"],args["model"])

面向对象编程介绍

1.面向对象和面向过程是相对的

2.定义类的格式为:

​ class 类名:

​ 方法列表

3.self表示调用方法的对象,一般在函数中第一个参数中传入,是该实例的内存地址

>>> class k():
     c = 6
     def __init__(self):
         self.c=1

>>> k.c
 6
>>> mk = k()
>>> mk.c
 1

4.__****___表示的是魔法方法

5._init_(self……)方法是object中的方法,重写该方法可以对类的对象进行初始化,当定义对象时就会调用这个方法

6._str_(self)方法相当于java中的tostring方法,是自动将对象转化为字符串

7.隐藏(也叫做私有)对象、属性是:__*****这样子命名的,相当于java中的类中私有属性,外部对象不能直接访问,但能通过其本身的方法函数调用

8._del_()方法相当于C++中的析构函数方法,销毁对象回收内存,只要有变量是某内存的引用,就不会调用_del_()方法

9.类属性:这个类所有的对象都可以共享的属性,但是也不能访问私有属性;可以用对象名.属性或者是类名.属性名进行访问。

10.类方法:在方法名的上面加上注解:@classmethod,可以直接通过类名调用

11.静态方法:采用@staticmethod注解进行修饰,且不需要默认传递的参数

12.__new__方法:构造类对象的时候调用的方法,必须返回当前类的对象,它是个静态方法

继承

1.继承的格式是在类的后面加括号加上要继承的类

单列模式


1.如果希望在整个系统中,某一个类只有一个实例存在,那么单例模式就能满足需求

class Person(object):
    def __new__(cls, *args, **kwargs):
        # 如果不存在这个对象
        if not hasattr(cls._instance):
            cls._instance=super().__new__(cls,*args,**kwargs)
        return cls._instance

工厂模式

1.工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式,虽然这样做会多做一些工作,但是给系统会带来更大的可扩展性和尽量少的修改量(可维护性)

2.人——>准备工作条件——>工作;工厂模式下:

人——>工厂提供准备条件——>工作

这样子就减少了相互之间的依赖性,使得自己设计的系统越来越优化。

异常处理

1.捕获异常的方式:

try:
	可能出现错误的代码块				
except(错误类型名 as msg):
	出错之后执行的代码块
else:
	没有出错的代码块
finally:
	不管有没有出错都会执行的代码块

2.抛出异常用raise

3.自定义异常要继承Exception类,对于自定义的异常要自己抛出,不能像系统中存在的异常一样可以自动抛出。

# 自定义的异常类
class exceptionautto(Exception):
    def __init__(self,leng):
        self.leng=leng
    def __str__(self):
        return '你输入的数据长度是:'+str(self.leng)

模块定义与调用

  1. 模块的搜索路径:(1)当前目录(2)如果当前目录没有,到环境变量中搜索,可以使用sys模块中的path变量查看所有路径(3)如果都找不到,搜索默认路径,linux系统默认路径一般为/usr/local/lib/python
  2. 与调用者同一个文件夹下可以直接“import 文件名”进行调用
  3. 调用方法用“import. 文件夹. 模块名”导入即可,还可以用as对导入的模块进行重命名
  4. if _name_==’_main_’:

​ 测试代码

​ 测试代码导入的时候不会被执行,主动调用的时候才会执行

  1. _all_=[表被调用的东西…],表示被别的包采用import 包名*方式导入时时能调用的东西

  2. python2和python3导入包 是有区别的:在python2中:要在包文件夹中加入_init_.py的文件才叫做包,但是有_init_.py文件在python3不会报错,所以为了兼容python3和python2,常常加上上面那个文件

模块的发布

  1. mymodule目录结构体如下:

|–setup.py

|–suba

| |–aa.py

| |–bb.py

| |–_init_.py

|–suba

​ |–cc.py

​ |–dd.py

​ |—_init_.py

  1. 编辑setup.py文件,格式固定如下:
from distutils.core import setup

setup(name="压缩包的名字",version="1.0",description="描述",auther="作者",py_modules=['suba.aa','suba.bb'.....])
  1. 构建模块

python3 setup.py build

  1. 生成发布压缩包

python3 setup.py sdist

模块安装与使用

1.安装的方式

​ (1)找到模块的压缩包拷贝到其他目录下去

​ (2)解压

​ (3)进入文件夹

​ (4)执行python3 setup.py install

内存回收

  1. 引用计数机制

  2. GC模块负责的主要任务:

    1. 为新生的对象分配内存
    2. 识别那些垃圾对象
    3. 从垃圾对象那回收内存
  3. Python中的循环数据结构以及引用计数:

    1. 标记-清除机制,首先标记对象,然后清除垃圾
    import psutil,os,gc
    def showMenSize(tag):
        pid=os.getpid()
        p=psutil.Process(pid)
        info=p.memory_full_info()
        memory=info.uss/1024/1024
        print(tag,memory)
    def func():
        showMenSize("c初始化")
        a=[i for i in range(100000)]
        b=[i for i in range(100000)]
        a.append(b)
        b.append(a)
        showMenSize("创建完对象之后")
        # 使用del删除后还是没有内存变化
        # del a
        # del b
    func()
    # 手动释放
    gc.collect()
    showMenSize("完成时候")
    
    1. 导致引用计数+1的情况
      1. 对象被创建
      2. 对象被引用
      3. 对象被作为参数,传入到一个函数中
      4. 独享作为一个元素,存储在容器中
    2. 有三种情况会触发垃圾回收:
      1. 当gc模块的计数器达到阙值的时候,自动回收垃圾
      2. 调用gc.collect(),手动回收垃圾
      3. 程序退出的时候,Python解析器会自动回收

列表推导式

a=[1 for i in range(1.10)]
输出结果为a=[1,1,1,1,1,1,1,1,1]
a=[i for i in range(1,10)]
输出结果为a=[1,2,3,4,5,6,7,8,9]
%后面的循环时嵌套在前面的循环中的
a=[i for i in range(0.2) for j in range(2,4)]
输出的结果为
a=[1,1,2,2]

正则表达式

  1. Python中的正则表达式是使用re模块来实现的

  2. re模块的方法:

    1. 单个字符匹配规则
    代码 功能
    \d 匹配数字,0-9
    \D 匹配非数字
    \s 匹配空白,空格,tab键
    \S 匹配非空白
    \w 匹配非特殊字符,a-z,A-Z,0-9,_,汉字
    \W 匹配特殊字符,非字母、非数字、非汉字
    . 匹配任意 1个字符除\n
    [ ] 匹配[ ]中列举的字符
    1. 多个字符匹配规则
    代码 功能
    * 前一个字符出现0或无限次
    + 前一个字符出现1次或无限次,即至少有1次
    ? 前一个字符出现1或0,要么有1次要么无
    {n} 前一个字符出现n次
    {m,n} 前一个字符出现m到n次
    import re
    str="fasdhf fasdfjl wrej oho jj"
    # 尝试从字符串的起始位置匹配一个规则(只匹配是否以***开头),匹配成功返回match对象,否则返回None
    # 可以使用group(nums)函数获取匹配成功的字符串
    # re.match(pattern,string,re.I)
    """
    (1) re.I 全写(re.IGNORECASE)
    表示使匹配时,忽略大小
    (2) re.M 全写(re.MULTILINE)
    多行匹配,影响 ^ 和 $的行为
    (3) re.S 全写(re.DOTALL)
    使点(.)匹配包括换行在内的所有字符
    (4) re.X 全写(re.VERBOSE)
    """
    result=re.match(".\w*",str,re.I)
    print(result.group())
    
    1. 匹配以***开头/结尾
    代码 功能
    ^ 匹配字符串开头
    $ 匹配字符串结尾
    1. 分组匹配规则
    代码 功能
    匹配左右任意一个表达式
    [^指定字符] 非,即除了指定字符以外都匹配
    ( ) 括号内的作为一个分组
    \num 引用分组num匹配到的字符串,前面已经写好了,后面直接用
    (?P/< name>) 分组起别名
    (?P=name) 引用别名为name分组匹配到的字符串
    1. 在正则表达式中加上r可以不用去加斜杠转译字符
    2. compile方法:将正则表达式模式编译成为一个正则表达式对象。
    import re
    reg=re.compile(pattern="/d{4}")
    result=reg.match("string")
    # 等效于re.match(pattern ,string),使用正则表达式对象可以有更高的效率
    
    1. search(pattern,string)方法,search在全文中匹配一次,匹配到就返回
    2. findAll(pattern,string)方法,查询字符串中某个正则表达式全部的非重复出现的情况,返回一个列表
    3. sub(pattern,repl(要替换成为的数据),string,count,flags)方法,将匹配到的数据进行替换
    4. split(pattern,string)字符串的分割
  3. 贪婪模式和非贪婪模式,默认的是贪婪的模式,要变成非贪婪模式,只需在匹配多个字符规则后面加上?

import re
# 非贪婪模式
rs=re.match('\d{6,9}','11112222233333')
print(rs.group())
# 贪婪模式
rs=re.match('\d{6,9}?','11112222233333')
print(rs.group())

多任务

多进程

  1. 系统分配资源的最小单位

  2. 第三方库为multiprocessing

  3. Process进程类的说明

    1. 参考文档https://docs.python.org/3.9/library/multiprocessing.html#multiprocessing.Process

    2. Process(group=None, target=指定的函数名, name=指定进程名, args=(函数的参数), kwargs={函数的参数}, , daemon=None)

    3. import multiprocessing,time,os
      # 带有参数的函数
      def danced(count):
          # 获取子进程id
          print("dance子进程" + str(os.getpid()))
          # 获取父进程的id
          print("dance父进程" + str(os.getppid()))
          for i in range(count):
              time.sleep(1)
              print("跳舞"+str(i))
      def sing():
          # 获取子进程id
          print("sing子进程"+str(os.getpid()))
          # 获取父进程的id
          print("sing父进程"+str(os.getppid()))
          for i in range(5):
              time.sleep(1)
              print("唱歌"+str(i))
      if __name__ == '__main__':
          # 使用多进程提高了执行的效率
          # 注意点,这里有三个进程,一个主进程,两个子进程
          # 获取主进程id
          print("父进程",end=":")
          print(os.getpid())
          # 创建进程
          # args元组参数列表来接收函数传递的参数,注意,单个元素的元组有一个逗号
          my_pro=multiprocessing.Process(target=danced,name="danced进程",args=(5,))
          my_pro2=multiprocessing.Process(target=sing,name="sing进程")
          # 开启进程
          my_pro.start()
          my_pro2.start()
      
    4. 获取当前进程id,使用os模块中的getpid()

      获取当前父进程id,使用os模块中的getppid()

    5. 注意点:

      1. 进程之间不共享全局变量:因为创建子进程会对主进程的资源进行拷贝,也就是说子进程是主进程的一个副本
      2. 主进程会等待子进程结束后再结束。例子,打开qq相当于主进程,登录两个qq号相当于两个子进程,
      3. 为了让主进程退出,子进程销毁,不让主进程再等待子进程的执行,需要设置守护主进程,设置的两种方法:
        1. 设置守护主进程方法:子进程对象.deamon=True,需要在start之前设置
        2. 销毁子进程方法:子进程对象.terminate()

多线程

  1. 系统调度的最小单位,它本身是没有资源的,使用的是进程中的资源
  2. 多线程的使用:
    1. 导入模块threading
    2. 创建线程threading.Thread(target=指定的函数名, name=指定进程名, )
    3. 开启线程start()方法
import threading,time,os
# 带有参数的函数
def danced(count):
    # 获取子线程id
    print("dance子线程" + str(os.getpid()))
    # 获取父线程的id
    print("dance父线程" + str(os.getppid()))
    for i in range(count):
        time.sleep(1)
        print("跳舞"+str(i))
def sing():
    # 获取子线程id
    print("sing子线程"+str(os.getpid()))
    # 获取父线程的id
    print("sing父线程"+str(os.getppid()))
    for i in range(5):
        time.sleep(1)
        print("唱歌"+str(i))
if __name__ == '__main__':
    # 使用多线程提高了执行的效率
    # 注意点,这里有三个线程,一个主线程,两个子线程
    # 获取主线程id
    print("父线程",end=":")
    print(os.getpid())
    # 创建线程
    # args元组参数列表来接收函数传递的参数,注意,单个元素的元组有一个逗号
    my_pro=threading.Thread(target=danced,name="danced线程",args=(5,))
    my_pro2=threading.Thread(target=sing,name="sing线程")
    # 开启线程
    my_pro.start()
    my_pro2.start()
  1. 注意点:

    1. 线程之间是无序执行的

    2. 同样的,主线程也会等待子线程结束后再结束,这时需要线程守护,其也有两种方法:

      1. threading.Thread(target=danced,name=“danced线程”,deamon=True)
      2. 线程对象.setDeamon(True)
    3. 线程之间是共享全局变量的,但会出现变量互斥问题,可以使用线程等待和互斥锁来解决这个问题:

      1. 线程等待用线程对象.join()函数,使得主线程等待该线程执行完后再执行下面的内容

      2. 互斥锁:

        # 创建锁
        lock=threading.Lock()
        # 上锁,同一把锁必须先开锁才能上锁
        lock.acquire()
        
        # 中间的额代码块同一时刻只能有一个线程在cpu中运行
        
        # 开锁
        lock.release()
        

数据分析

matplolib

  1. 最流行的 Python底层绘图库,主要可以做数据可视化图标
  2. 文档:https://matplotlib.org/stable/tutorials/introductory/usage.html#sphx-glr-tutorials-introductory-usage-py
  3. 例子:
#用图片展示十点到十二点的每一分钟的温度则线图
from matplotlib import pyplot as plt
import random
import matplotlib
# 显示中文
font = {'family' : 'Microsoft Yahei',
              'weight' : 'bold',
              'size'   : '10'}
matplotlib.rc('font', **font)
# 坐标
x=range(0,120)
y=[random.randint(20,30) for i in range(120)]
# 图片大小设置
plt.figure(figsize=(20,8),dpi=80)
# 画图
plt.plot(x,y)
# 设置x轴的标签
_x=list(x)[::10]
_x_labels=["十点{}分".format(i) for i in _x]
plt.xticks(_x,_x_labels,rotation=45)

plt.xlabel("时间")
plt.ylabel("温度 单位(℃)")
plt.title("10点到12带你每分钟气温变化")
plt.show()

numpy

  1. 文档:https://numpy.org/

算法练习

排序算法

# 冒泡排序
def bubbleSort(l):
    i=0
    while(i < len(l)):
        # 针对有序的列表或者子列表进行优化
        bchang=False
        j=i+1
        i+=1
        while(j < len(l)):
            if l[j]=0 and num0):
        for i in range(gap,len(temp)):
            num=temp[i]
            j=i-gap
            while j>=0 and num=num and lefttemp[j]:
                min=temp[j]
                mintag=j
        temp[mintag]=temp[i]
        temp[i]=min
    return temp

你可能感兴趣的:(学习,python)