安装python

推荐安装anaconda3(linux)

wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2021.05-Linux-x86_64.sh

dash Anaconda3-2019.10-Linux-x86_64.sh

根据提示安装,如果还是系统自带的python

sudo gedit ~/.bashrc

export PATH="/home/pc/anaconda3/bin:$PATH"

pc为系统的用户名,请修改成自己的系统用户名,请勿在root用户下安装anaconda3

注意:如果使用anaconda3,请设置Path环境变量,/Anaconda3,/Anaconda3/Scripts,/Anaconda3brary/bin,这3个路径都需要设置

Windows和mac 到官网下载安装包,直接下一步安装

mac安装了Homebrew,可以使用brew install python3

Windows设置环境变量,PATH 安装路径

现在liunx一般都会自带有python3,如果没有可以安装一下

apt install python3

yun install python3

注意一下python2.x和python3.x这两个版本是不兼容的,要区分开

检查是否安装成功,在命令行或者终端输入python3 回车 没有反应或者报错就说明没有安装成功或者可能出问题了 Windows的一定要注意PATH系统变量

因为Python语言从规范到解释器都是开源的,所以存在多个解释器

例如CPython,安装python3.x时就可以直接获取到一个官方版本的解释器:CPython,因为是使用C语言开发的,所以叫CPython

在命令行或者终端,输入输入python3 回车,如果出现了»> 那么当前状态是python的交互模式

在交互模式下输入exit(),退出python的交互模式

在交互模式下执行第一个程序 print(“hello,world”)

回车输出hello,world,这是简单的打印字符串

除了使用交互模式执行程序,又可以使用.py,在命令行或者终端下 python hello.py,如果报错,请检查程序是否出错或者该文件是否在当前目录下

交互模式可以直接输出结果,但是使用.py文件却不会,想要输出结果,必须使用print()打印出来

一个好的开发工具往往可以达到事半功倍的效果,例如pycharm和Visual Studio Code,我使用的是Visual Studio Code

print()接受多个输出,使用“,”分隔开,也可以输出整数

当你想让用户输入一点东西的时候,python提供了一个input(),用法如下 name = input() 将输入的值存放到一个变量里

input()还提供了提示功能,显示一个字符串,例如:input(“xxxxx”)

我想知道这个变量的内容咋办,可以在交互模式下直接输入变量名,回车,就可以查看该变量的内容 又可以使用print()打印下来

那么什么是变量呢?

在计算机程序中,变量不仅可以为整数或浮点数,还可以是字符串

输入是Input,输出是Output,输入输出统称为Input/Output,或者简写为IO

以#开头的语句是注释,注释是给人看的,解释器会忽略掉注释,注释可以是任何内容

其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块

注意:python区分大小写,搞错了大小写,程序可能会报错。缩进建议使用4个空格

python能直接处理的有:整型,浮点型,字符串,布尔值,空值,变量,常量

python可以处理整型任意大小的整数,也可以使用二进制代表整数、

浮点型就是小数,使用科学记数法表示时,一个浮点数的小数点位置是可变的,所以小数又叫浮点型,表示很大或很小的浮点数,必须用科学计数法表示

字符串是使用"“和’‘括起来的任意文本,‘‘或"“本身只是一种表示方式,不是字符串的一部分

字符串内部包含’又包含"怎么办?使用转义字符来标识,转义字符可以转义很多字符,比如n表示换行,t表示制表符,字符本身也是可以转义的,所以\表示的字符就是\

为了简化,Python还允许用r’’,用来表示’‘内部的字符串默认不转义

在交互式命令行内输入,在输入多行内容时,提示符由»>变为…,提示可以接着上一行输入,注意…是提示符,不是代码的一部分

多行字符串’‘‘xxx’’’,可以在前面加上r使用

布尔值只有两种值,分别是True和False,在计算机中布尔值要么是True,要么是False,在python中可以直接使用True、False表示布尔值,注意大小写

and是与运算,只有所有值都为True时,and运算结果才是True

or运算是或运算,只要其中有一个为True,那么or运算结果就是True

not运算是非运算,它是一个单目运算符,专门把True变成False,False变成True

空值,使用None表示空值,这个空值不是0,因为0是有意义的,代表什么都没有

在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。

变量在程序中用一个变量名表示,变量名必须是大小写英文、数字和_的组合,且不能用数字开头,

变量名 = 任意数据类型,这个过程叫变量赋值,变量可以反复赋值

这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。

例如golang就是一个静态语言,不能跨数据类型来赋值

x = 1

x = x+1

这个是计算新的值,并且重新赋值给该变量

a = “hello”

这时Python解释器干了两件事情:

在内存中创建了一个’hello’的字符串;

在内存中创建了一个名为a的变量,并把它指向’hallo’。

可以把一个变量a赋值给另一个变量b,这个操作实际上是把变量b指向变量a所指向的数据

因为程序是从上往下执行的,一定要理清逻辑

常量就是不能变的变量,在python中使用大写表示一个常量,例如: ABC =123

但这个常量还是可以被修改,因为Python没有任何机制可以保证该常量不会被改变,这个很奇怪

/除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数

当使用//除法时,两个整数的相除就可以是整数

想要做精确的除法,就必须使用/了

// 除,永远是整数

字符编码 python提供了字符转编码函数ord()和编码转字符函数chr()

Python可以使用编码来输出内容

Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节,可以转成bytes类型,方便传输和保存数据

在Python中bytes类型的数据用带b前缀的单引号或双引号表示:a = b"hallo word”

str和bytes类型内容显示没有差别,但是bytes的每个字符都只占用一个字节

在Python中,可以使用encode()方法来指定编码,例如: ‘hallo’.encode(‘ascii’) b’hallo’

注意:纯英文的str可以使用ASCII编码为bytes,显示内容一样,但是包含了其他语言(比如中文)的str不能使用ASCII编码,Python会报错,含有其他语言的str请使用UTF-8编码

如果想把bytes转为str,可以使用decode()方法

注意:如果bytes中包含无法解码的字节,decode()方法会报错

如果bytes中只有一小部分无效的字节,可以传入errors=‘ignore’忽略错误的字节

计算str包含多少个字符,可以用len()函数

len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数 为了让Python按UTF-8编码读取,一般都会在文件开头声明一下: # !/usr/bin/python3 # – coding: utf-8 –

第一行是告诉计算机系统这是一个Python可执行程序,注意Windows会忽视这个

第二行是告诉Python,请按照UTF-8编码读取源代码

注意:声明并不代表文件是UTF-8编码的,请确保文本编辑器使用UTF-8 without BOM编码

如果想一些内容可以根据变量变化,那么就用到格式化字符串

在Python中,采用的格式化方式和C语言是一致的,用%实现

‘Hello, %s $%d ’ % (‘world’)

常见的占位符有:

%d – 整数 %f – 浮点数 %s – 字符串 %x – 十六进制整数

注意:%s永远起作用,它会把任何数据类型转换为字符串!!!

如果字符串里面的%只是普通字符,那么使用%%来代表一个%(转义)

还有一个格式化字符串方法:format()

它会用传入的参数依次替换字符串内的占位符{0}、{1}……..

例如:

‘hello,{0}’.format(‘world’)

Python 3的字符串使用Unicode,直接支持多语言

当str和bytes互相转换时,需要指定编码

列表(list),一种有序的集合,可以随时添加和删除其中的元素,使用[]来表示,例如: abc = [‘a’,‘b’,‘c’]

可以使用索引来访问列表的每一个元素,索引是从0开始,例如:

abc[0] ‘a’

注意:索引超出范围时,Python会抛出一个IndexError错误,记得最后一个元素的索引是len(classmates) - 1

如果想获取最后一个元素,不知道索引,又怕抛出错误,可以使用-1方法,例如:

abc[-1] c

以此类推,可以获取倒数第2个、倒数第3个,-2,-3

因为这个列表是可变的有序的列表,所以可以在列表中追加元素到末尾,例如:

abc.append(’d’) abc [‘a’,‘b’,‘c’,’d’]

当然也可以添加元素到指定的位置,例如:

abc.insert(1,‘1’) abc [‘a’,‘1’,‘b’,‘c’,’d’]

删除列表末尾元素,使用pop()方法,例如:

abc.pop() ’d’ abc [‘a’,‘1’,‘b’,‘c’]

删除指定位置的元素,使用pop(),括号中填写索引位置

abc.pop(1) ‘1’ abc [‘a’,‘b’,‘c’]

如果想把某个元素换成其他元素,可以直接赋值给对应的索引位置,例如:

abc[0]=‘abc’ abc [‘abc’,‘b’,‘c’]

列表里面的元素数据类型可以不同,例如:

a = [‘hallo’,666,False]

列表里面可以包含其他列表,反复嵌套,例如:

a = [‘hallo’,‘word’,[‘123’.‘abc’]]

注意:这个a列表只有3个元素,其中的a[2]又是一个列表,可以拆开理解,例如:

123 = [‘hallo’,‘word’]

abc = [‘666’,123,‘abc’]

想拿到’hallo’,可以写成123[1]或者abc1

这个可以看成一个二维数组

注意:当一个列表中一个元素也没有,那么就是一个空的列表,长度为0,a=[] len(a) 0

还有一个有序列表叫元组(tuple),和list很相似,不过这个一但初始化就不能修改

没有添加元素和删除元素的方法,但是可以正常使用获取元素的方法,获取方法和list一样,就是不能赋值成另外的元素

那么这个列表不能改变,那么有什么意义?因为tuple不可变,所以程序更安全

当定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来

如果要定义一个空的tuple,可以写成()

正确定义只有一个元素的tuple,例如:

a = (1,) a 1

为啥这样呢?因为括号()可以表示tuple,又可以表示数学公式中的小括号,防止Python按照小括号来计算,避免歧义

关于可以’改变’的tuple:实际上改变的是list,因为tuple里面可以有list列表,所以可以’改变'01


全局变量和局部变量

一般在函数内部定义的变量,为局部变量,在函数外部定义的变量为全局变量

因为作用域的问题,一般在函数内部不能真正修改到全局变量

可以使用关键字global来处理

abc = None

def xyz():

    global abc

    abc="hallo"

    return a

print(abc)  // 观察这个变量和下面的变量的区别

print(xyz())

print(abc)  // 观察这个变量和上面的变量的区别

nonlocal 可以用于在函数或者其他作用域中使用上层(非全局)的变量,例如:

def xyz():
    abc="hallo"

    def go():
        nonlocal abc
        return abc

    return go()

print(xyz())

函数

调用函数 函数名()

python中内置了大量的函数,可以直接调用,例如:

int(“666”) // 666

因为函数本身可以理解为是一个引用类型,所以函数是可以赋值给变量,例如:

a = int a(“123”) // 123

定义函数

def为定义一个函数的关键字,定义一个函数例如: def abc(i): print(i)

如果有一个函数定义在另一个文件里,可以在当前文件的当前目录下,使用from abstest import导入函数

空函数: def no(): pass

pass语句用于什么都不干,可以用于占位

检查函数传入的参数

检查数据类型可以使用isinstance()

isinstance(1,int) // 返回布尔值,可以搭配if判断语句使用

如果想要手动设置异常,可以使用raise语句,例如:

def no(i):
    if not isinstance(i,(int)):
        raise ValueError("no函数的传参必须为整数")

no('1')

函数内部可以使用return来返回函数结果

使用return返回不了值,主要是没有把值取出来,例如

def a(x):
    return x

b = a(1)
print(b) // 1

python的函数参数灵活度很高

def a(x,i=1) // 默认i为1

必选参数在前,默认参数在后,当不需要默认参数可以直接覆盖掉,灵活性很高

当参数的个数不明确时,可以把参数当成list或tuple传进来,例如:

def a(x):
    abc = 0
    for a in x:
        abc=abc+a
    return abc
a = a([1,2,3])

print(a) // 6

如果已经有一个list或tuple,想传进来:

def xyz(*x):
    abc = 0
    for a in x:
        abc=abc+a
    return abc

b = [1,3,5]
a = xyz(*b)

print(a)

关键字参数可以传入0或者任意个参数,而这些参数会变成一个tuple

def abc(i,**n): print(‘i:’, i, ’n:’, n)

abc(“abc”)

如果已经有一个tuple,想传入: b = {1,3,5} abc(**b)

如果想限制关键字参数,例如:

def xyz(i,n,*,name,age):
    print(i,n,name,age)
xyz(1,2,name="hallo",age=18)  // 1 2 hallo 18

*后面的参数被认为是命名关键字参数,限制只能使用该参数名

如果参数中已经有了可变参数,后面跟着的命名关键字参数就不需要*来分隔了

命名关键字参数必须要传入参数名,否则报错,如果命名关键字参数已经有默认值,可以不用传入

递归函数

递归函数就是这个函数反复调用它本身,例如:

从1加到100,1+2+3+…+100

def xyz(n):
    if n == 1:
    return 1

    return n+xyz(n-1)

a = xyz(100)

print(a) // 5050

尾递归优化

递归调用次数过多,会导致堆栈溢出,溢出就是超出了最大上限的堆栈

而解决因为递归而导致的溢出的方法就是尾递归优化

但是Python解释器目前不支持尾递归优化,就算使用尾递归方式,也还是会导致堆栈溢出

def abc(n):
    return xyz(n,1)

def xyz(n,go):
    if n == 1:
        return go

    return xyz(n-1,n+go)

a = abc(100)

print(a)

切片,顾名思义,就是取部分值,例如:

a = [1,2,3,4,5]

a[0:3] // [1,2,3]

索引从0开始,到3为止

支持倒数切片

a[:-1] // [1,2,3,4]

如果开头为0,可以省略不写,倒数第一个为-1

a[::2] // [1, 3, 5] 每两个取一个

a[:] // 复制一个一样的list

tupel也可以使用切片,但是操作结果还是tuple

a = (0,1,2,3)

a[:3] // (0,1,2)

甚至连字符串都可以切片,结果还是字符串

a = “hallo”

a[:2] // hallo

迭代

读写文件

abc = open(‘1.txt’,‘r’) go = abc.read(6) # 可以指定读取的数量,如果为空则读取全部 print(go) abc.clsoe() # 这个用来关闭文件

r为只读,w为写入,a为追加,rb为以二进制方式只读,wb为以二进制方式写入,ab为以二进制方式追加

abc = open(‘1.txt’,‘w’) abc.write(“hallo word!!” * 6) # 写入6条数据 abc.close()

abc = open(‘1.txt’,‘r’) data = abc.readline() print(“3:%s” % data) # 读取指定行数的数据,这里为读取3行数据 abc.close()

如果想多钱全部数据,并且返回的是一个列表,列表的每一个元素为都为每一行数据,可以: abc = open(‘1.txt’, ‘r’) data = data.readlines()
print(type(data)) for a in data: print(a) data.close()


if判断

data = 10
if data >=18:
    print("成年了!")
elif data>=6:
    print("义务教育")
else:
    print("未成年!!!")

输入输出

data = int(input("请输入数据"))
print(data)

类型转换(Python是弱类型语言,弱类型指不能对变量声明类型,只能声明数据的类型)

int()整数,str()字符串,float()浮点数,bool()布尔数,list()列表,tuple()元组,chr()字符,unichr()Unicode字符等等

例如:

data1 = "123"
data2 = 123
print(isinstance(data1,str))
print(isinstance(data2,int))
data3 = int(data1)
data4 = str(data2)
print(isinstance(data3,int))
print(isinstance(data4,str))

运算符

+加,-减,*乘,/除,//取整除,%取余,**指数

优先级和普通的算数规则一样,指数大于乘和除,取余,取整除大于加和减

字符串不能和整数相加,必须将字符串或者整数转换,字符串为拼接,整数为算数

赋值运算符

=,将右边赋值给左边的变量,可以给多个变量赋值,例如:a = b = c = 666或者a,b,c = 666,123,100

a+=1 :a=a+1,a-=1:a=a-1,a*=1::a=a*1,a/=1::a=a/1,a//=1: :a=a//1,a%=1:a=a%1 ,a**=1:a=a**1

==比较是否相等,!=比较不相等,>大于,<小于,>=大于等于,<=小于等于

and和运算符(只有当比较全部为true才为true,否则都为false),or或运算符(只有当比较有一个为true才为true,全部为false才为false),not取反运算符(只有当比较为true才为false,当比较为false才为true)


for循环和while循环

for循环可以遍历任何以序列排序的东东,比如列表和字符串

for a in "hallo word":
    print(a)

或者

fot a in range(1,100):
    print(a)

range支持3个参数,分别是起始,结束,以及步长

while循环,在某个条件下为true下才会执行里面的语句

data = 0
while data < 10:
    print(data)
    data+=1

获取字符串或者列表的长度,len(data)

查找某些内容是否在字符串的某些地方中存在(如果不存在,返回-1),find(str,beg=0,end=len(strdata))

str为要查找的字符串,beg开始查找的位置,end结束查找的位置


错误处理

读取文件错误(当文件不存在时) try: abc = open(‘data.txt’, ‘r’) print(abc.read()) except FileNotFoundError: print(‘文件没有找到,请检查文件名称是否正确’)

try…except语句可以处理程序运行过程中可能出现的异常


面向对象

class ClassName():
    'test 定义类'
    name = 'hallo'
    age = 20
    def abc(self): # 实例方法
        print(self.name)
        print(self.age)
    
className = ClassName() # 实例化类
className.abc() # 调用类的方法

导入类

from hallo import ClassName
className = ClassName() # 实例化类
className.abc() # 调用类的方法

构造函数

class ClassName():
    name = 'hallo'
    age = 20
    def __init__(self, name,age):
        self.name = name
        self.age = age

a = ClassName('hahaha', 18)
b = ClassName('abc', 100)
print(a.name)
print(a.__dict__)
print(b.name)
print(ClassName.name)


class ClassName():
    name = 'hallo'
    age = 20
    sum = 0
    def __init__(self, name,age):
        self.name = name
        self.age = age
        self.__class__.sum += 1 # 每调用一次构造函数就触发+1
        print(self.__class.sum)

类方法

class ClassName():
    sum = 0
    @classmethod
    def Sum(cls):
        cls.sum += 1
        print(cls.sum)
        
ClassName.Sum()

静态方法

class ClassName():
    @staticmethod
    def hallo(name, pass):
        print(name,pass)
        
ClassName.hallo('hallo','123456')
abc = ClassName()
abc.hallo('hhhhh','666123')

类的成员的公开性与私有性

class ClassName():
    name = 'hallo'
    age = 20
    __pass = ''
    def __abc(self): # 给类的成员开头加上__将表示该成员是私有的,无法在类外部使用
        print(self.name)
        print(self.age)

注意: 如果前后都有__,则表示公开的,如构造函数__init__,只有开头有__才是私有的,默认是公开的

Python提供一种私有保护机制,当在类外部使用时,Python会将其认为是全新的,私有的是无法被更改的,例如:

class ClassName():
    name = 'hallo'
    age = 20
    __pass = '123'
    def abc(self):
        print(self.name)
        print(self.age)

classname = ClassName()
classname.__pass = '123456'
print(classname.__dist__)
print(classname._classname__pass) # 实质是访问类里面的私有__pass

可以看到原来的__pass变成了_classname__pass这个全新的名称,而显示__pass是新的'12345’

类的继承

class ClassName():
    def __init__(self):
        self.a = 123
        self.b = 666
    def hhh(self):
        print('hallo word')
    def gogo(self):
        print('hallo abc')
class Hallo(ClassName):
    def __init__(self):
        super().__init__() # 调用父类的__init__,当子类重写的父类的方法后,还想调用父类原来的方法,可使用super(),该语句块实质上也是在重写的父类的__init__方法,因此需要在子类的__init__调用父类原来的__init__
    def abc(self):
        return self.a + self.b # 继承父类的属性
    def gogo():
        print('hallo python') # 重写父类的gogo方法

hallo = Hallo() hallo.hhh # 调用父类的hhh方法 hallo.a # 调用父类的属性


正则表达式

判断某个字符串中是否存在某个字符

import re
abc = "hallo word"
xyz = re.findall("hallo",abc)
if len(xyz) > 0:
    print("字符串包含hallo")
else:
    print("字符串不包含hallo")

筛选出某个字符串中存在的数值

import re
abc = "0hallo1 word2"
xyz = re.findall('\d',abc)
print(xyz)

\d是元字符,\d也是概括字符集,\d可以使用[0-9]实现相同的效果

字符集

import re
abc = "aha, aca, ada, aaa, aea"
xyz = re.findall('a[ha]a',abc)
// xyz = re.findall('a[^ha]a',abc) // aea,^是取反
// xyz = re.findall('a[c-e]a',abc) // aca,ada,aea,c-e表示c,d,e
print(xyz) // aha和aaa

数量词

import re
abc = "hallo word hhhhhh"
xyz = re.findall('[a-z]{3,6}',abc) // 数量词使用{}包括,3,6表示匹配3到6个字符
print(xyz)

贪婪与非贪婪

匹配会最大匹配,像上面的数量词的例子,hallo并没有因为3而匹配hal,而是最大匹配,直到匹配的字符不符合才停止,这就是贪婪匹配

import re
abc = "hallo word hhhhhh"
xyz = re.findall('[a-z]{3,6}?',abc)
print(xyz)

上面的例子就是非贪婪的,匹配会最小匹配

匹配0次或无限次

import re
abc = "aba abcc abccd abc"
xyz = re.findall('abc*',abc)
print(xyz)

匹配1次或无限次

import re
abc = "aba abcc abccd abc"
xyz = re.findall('abc+',abc)
print(xyz) // abcc,abccd,abc

匹配0次或1次

import re
abc = "aba abcc abccd abc"
xyz = re.findall('abc?',abc)
print(xyz) // abc abc abc

边界匹配符

由于匹配只针对最小匹配,最大匹配无效,例如

import re
abc = "123456789"
xyz = re.findall('\d{3,6}',abc)
print(xyz) // 123456,明明不符合6,但是还是输出了

边界匹配符就是解决这个问题的

import re
abc = "123456789"
xyz = re.findall('^\d{3,6}$',abc) // ^表示该位置开始匹配,$表示该位置结束匹配
print(xyz) 

import re
abc = "abc abc xyz hallo abc abc xyz word"
xyz = re.findall('(abc)(xyz)',abc)
print(xyz) 

json反序列化(json字符串转python字典)

import json
abc = '{"name": "admin", "pass":"abc123"}'
xyz = json.loads(abc)
print(type(xyz))  // dict字典
print(xyz) 
print(xyz['name']) 
print(xyz['pass']) 

json序列化(python字典转json字符串)

import json
abc = [
    {"name": "admin", "pass":"abc123"},
    {"name": "root", "pass":"1234567"}
]
xyz = json.dumps(abc)
print(type(xyz)) // str字符串
print(xyz) 

枚举

from enum import Enum
class ABC(Enum):
    ID = 1
    USER = 2
    PASS = 3
print(ABC.ID)
print(type(ABC.ID)) // ABC类型
print(ABC.ID.name) // 枚举名称
print(ABC.ID.value) // 枚举值
print(ABC.ID == ABC.USER) // 枚举的比较,不支持大小比较,只支持等值比较
print(ABC.ID in ABC.USER)
for i in ABC.__members__.items():
    print(i) // 遍历枚举名称和值,如果只要枚举名称,则去掉.items()

枚举和类的区别:枚举值不可变,枚举具备防止枚举名称重复的功能