清明节要完成的事情一直拖到了现在,虽然大部分都是基础,但终究是自己学到的!通过学习你会发现python的库真的是很多,就比如我现在正在学的爬虫,只要使用几个库基本上就算是入门了,当然深入还是需要自己的努力。对于我而言,python更多的是一种处理工具,它对很多的事件处理有着相当优秀的表现。希望在这条路上能越走越远,加油!当然了,也欢迎大家指出我的不足,一起学习。在这里奉献上我的个人博客:赵日天的暖心小窝
都是自己平时学习时候的一些总结,欢迎大佬们赐教。

第一章:Python的安装及使用

1.1下载python版本

首先在官网下载python版本,我在官网下载的是3.9.2版本。

1.2安装Python

安装python版本时,如果在最后没有勾选to path选项,则需要后面配置环境变量,我们在这里直接勾选 Add python 3.9.2 to path选项。

3.python安装测试

python安装好后可以在命令行cmd中输入python检查是否安装好,安装好后我们就可以在python自带的Python IDLE中直接运行python了,如果觉得不方便可以下载一些其它的编译器,比如PyCharm、K0modo、Eclipse、vscode等一些其它的适合自己的编译器。

第二章.Python的基本知识

2.1 Python的语法特点

2.1.1代码注释

Python代码的注释分为单行注释和多行注释,Python中单行注释中以#开头,如:

print("茅檐低下,溪上草青青。")

添加注释的目的是解释代码的功能和用途。注释可以出现在代码的任意位置,但是需要注意的是,注释不能分割关键字和标识符。例如:

aaa=float(#这是一个单行注释input("请输入商品的价格:"))

这句话在这里就是错误的。多行注释在python中用单引号 (’’’) 或者三个双引号(""")将注释括起来。

2.2.2代码缩进

python中要注意代码缩进,如果代码的缩进是不正确的,那么就会产生编译错误。实现代码缩进的方法有两种,包括使用空格和键。通常一个键作为一个缩进量,4个空格代表一个即一个缩进。

2.2.3.编码规范

在python中编写代码时,需要遵循以下规范:

①不能在行尾加分号;

②每行的字符数最多不超过80个,如果超过,建议使用小括号将多行的内容隐式连接起来;

③每个import语句只导入一个模块,尽量避免一次导入多个模块;

④尽量避免在循环中使用+和+=运算符进行累加字符串。

2.2.4换行问题

如果是Linux/UNTX操作系统,换行字符为ASCII LF(linfeed);如果是DOS/windows操作系统,换行字符为ASCII CR LF(return+linefeed);如果是Mac OS操作系统,换行字符为ASCII CR(return)。即我们在windows中操作时只需要像在C语言中换行一样输入 \n 即可。

如果程序代码超过一行,可以在每一行的结尾添加反斜杠(),继续下一行,这与C/C++的语法相同,需要注意的是,在 \ 之后不要加注释文字。

如果要将数行表达式写成一行,只需在原来除最后一行以外的每一行的结尾添加分号(;)即可,例如:

>>>a='苹果';b='香蕉';c='橙子'
>>> a
'苹果'
>>>b
'香蕉'
>>>c
'橙子'

2.2标识符与保留字

标识符用来识别变量、函数、类、模块及对象的名称。标识符的第一个字符必须是字母表中的下划线或者下划线(_),并且变量名之间不能有空格。

保留字跟关键字都不能当作标识符,我们可以在cmd中查看Python的保留字

>>>import keyword
>>>keyword.kwlist

2.3变量

①变量名必须是一个有效的标识符。

②变量名不能和保留字冲突

③尽量选择有意义的单词作为变量名

④谨慎使用大写字母O和小写字母i

⑤变量赋值与C语言中一样采用(=)赋值

⑥Python的内置函数 type()用来直接查询变量所指的对象类型,与JavaScript中的typeof()用法相同,都可以用来查看变量类型。

2.4基本数据类型

2.4.1数字类型

python 3.X版本中有两个简单的基本数据类型,数字类型和字符串类型。

数字类型包括 int 、float、bool、complex(复数)。需要注意的是,数值的除法(/)总是会返回一个浮点数,要获取整数则需要使用 // 操作符

2.4.2字符串类型

在Python中,字符串属于不可变序列,通常使用单引号、双引号或者三引号括起来。使用的方法没有多大差别,但是需要

注意的是单引号和双引号的字符序列必须在一行上,而三引号内的字符序列可以分布在连续的多行上。

2.3.3数据类型的相互转换

数据类型的强制转换与C语言的使用方法相差无几,比如:int()、float()、str()

2.5运算符和优先级

Python语言支持的运算符包括算术运算符、比较运算符、赋值运算符、逻辑运算符、位运算符、成员运算符和身份运算符

2.5.1算术运算符

算数运算符有:+ - * / % ** // 其中加减乘模与C语言相同,**指的是幂运算,如:a**b指的是a的b次方,而//运算符则指的是返回相除后结果的整数部分,如 7//3得到2,这个与C语言中的除法相同,而在python中的除法则返回的是浮点数,这里与我们在C语言中所学是不同的,C语言返回的是整数,而在这里除法反水的是浮点数。

2.5.2比较运算符

比较运算符有: == != > < >= <= 这些比较运算符与C语言中的均相同,它返回的是一个bool类型的值,true或者false

2.5.3赋值运算符

赋值运算符有: = += -= = /= %= **= //= 这里的运算过程与C语言中的基本相同,之前介绍过// 和//**所以在这里就不做过多解释。

2.5.4逻辑运算符

逻辑运算符:and or not 这里与数字电路中的与、或、非 相同,取值也相同。

2.5.5位运算符

位运算符把数字当作二进制来进行计算。

它支持的运算符有

2.5.6成员运算符

python语言还支持成员运算符,其测试例中包含了一系列的成员,如字符串、列表、元组。成员运算符包括in 和not in 。例如,x in y表示:若x在y序列中,则返回True;x not in y 表示:若 x 不在y序列中,则返回True。类似于JavaScript中的instanceof,用于判断前者是否属于后者的实例对象。

2.5.7身份运算符

Python语言支持的身份运算符为is和not is。其中,is判断两个标识符是不是引用自一个对象:is not 判断两个标识符是不是引用自不同的对象。

2.5.8运算符的优先级

in与in not 运算符应用于列表(list)。is运算符用于检查两个变量是否属于相同的对象;is not 运算符则用于检查两个变量是否不属于相同的对象。

2.6.Python的输入与输出

2.6.1 input()函数

input()用于输入数据,但是输入的内容都会被当作字符串来处理,所以当我们后面要对字符串的内容进行处理时经常需要对输入的内容进行强制类型转换

2.6.2 print( )函数

print( )函数可以输出格式化的数据,与C/C++语言的printf( )函数功能和格式相似。print( )函数的基本语法格式如下:

print(value,…,stp=’ ‘,end=’\n’) #此处只说明了部分参数。

在这里只介绍两个参数:stp和end。stp是用于设置多个要输出信息之间的分隔符,默认的分割符为一个空格,也就是我们用 ,表示的都会默认按照一个空格输出,当然我们也可以直接在print函数输出时对其进行修改。end参数用于print函数输出完所有信息后添加的符号,默认为换行符,我们也可以直接对其进行修改。这些极大地方便了我们的使用。

print( )在使用时有许多需要注意的地方。我们如果想一次性输出多个内容,而且不换行,可以将要输出的内容使用英文半角逗号隔开。

第三章.程序的控制结构

3.1 程序控制

程序控制主要包括三个:顺序结构、选择结构、循环结构。基本上每种编程语言都有相同的控制结构,在这里就不做过多解释。

3.2选择结构

选择结构也叫做分支结构,用于处理在程序中出现两条或者跟多执行路径可供选择的情况。选择语句可以用分支语句来实现。分支语句主要为if语句。

if的使用方法与C语言的用法相同。不过需要注意的是if和elif以及else的后面都要加上冒号,以及elif和else不能单独存在,必须配合if语句一起使用。if和else同样也可以结合pass使用,比如当条件符合时我们不对其做任何操作,此时就可以使用pass语句。pass语句的使用主要是为了保持程序结构的完整性,pass不做任何事情,一般用作占位语句。

下面给出一个多重条件判断三角形的例子:

a=int(input("请输入三角形的第一条边:"))
b=int(input("请输入三角形的第二条边:"))
c=int(input("请输入三角形的第三条边:"))
if a==b and a==c:print("等边三角形")
elif a==b or a==c or b==c:print("等腰三角形")
elif a*a+b*b==c*c or a*a+c*c==b*b or b*b+c*c==a*a:print("直角三角形")
else:print("一般三角形")

3.3布尔表达式

bool表达式的结果只有true和false,True等价于1,False等价于0。我们可以使用type( )方法来查看true和false的类型,同样也可以使用bool( ) 函数将其他值转换为布尔类型。其它用法与JavaScript中的boolean用法是相同的,所以在这类不做过多介绍。

3.4循环控制语句

循环控制中的几个关键语句主要是:while和 for、continue和break以及else语句。

while语句与C语言中用法相同,但是for循环却不同。

for语句通常由条件控制和循环两部分组成。

for <variable> in <sequence>:语句
else:语句

其中 是一个变量名称;是一个列表,经常会搭配range( )函数进行数字遍历使用。else语句执行的时机是当fou语句都没有运行,或者最后一个循环已经运行时。else语句是可以省略的。

else语句在C语言中只可以和if搭配使用,但是在python中可以搭配for、while使用。它的执行时机是当for循环被执行完或者while循环条件为False时,else语句才会被执行。需要特别注意的是,如果循环被break语句提前终止,那么else语句不会被执行。

pass是空语句,主要是为了保持程序结构的完整性,pass不做任何事情,一般用作占位语句。

在这里需要介绍一下range( )函数。在使用range( )函数时,如果只有一个参数,那么表示指定的stop;如果有两个参数,则表示指定的start和stop,范围为[start,stop);如果三个参数都存在时,最有一个参数则是步长step。如果需要遍历数字序列,通常会用到range( )函数,解和循环控制语句,会达到事半功倍的作用。

第四章 序列的应用技能

Python中内置了5个常用的序列,即集合、列表、元组、字典和字符串

4.1认识序列

4.1.1 索引

序列中的每个元素都有编号,也称为索引,索引从0开始。索引与我们在C语言数组中学到的相同,都是从0开始,使用方法也相同。值得注意的是,这里的索引支持负数,负数则是表示从右往左开始计数。采用负数作为索引时,是从 -1 开始的,也就是最右边的元素的下标为-1

4.1.2切片

访问序列元素还有另一种方式,那就是切片。它可以访问一定范围内的元素。通过切片操作可以生成一个新的序列。

sname[start,end:step]

sname表示序列的名称;start表示切片开始的位置,如果不指定则默认为0;end表示切片结束的位置,如果不指定,则默认为序列是序列的长度;step表示的是切片的步长,如果省略,则默认为1。

name=['张三','王五','张锋','马六','陈平']
names[1:5]      #访问从从左边数第2到第五个
names[0:5:2]
['张三','张锋','陈平']

Python中切片的功能与JavaScript中的slice()方法很相似,在这里列出JavaScript的使用方法

4.1.3序列相加

通过 + 操作符,可以将两个序列相加。需要注意的是集合和字典不支持相加。 "+"操作符经常用于字符串和列表元素的组合

>>>x=[100,200,300]+[400,500,600]+[700,800,900]
>>>x
[100,200,300,400,500,600,700,800,900]
>>>y=['数学','英语','语文']
>>>z="我最喜欢的学科是"+y[1]
>>>print(z)
>>>我最喜欢的学科是英语

4.1.4序列相乘

*号运算符经常用于重复列表中的元素,例如

>>>x=["数学","英语","语文"]*3
>>>x
["数学","英语","语文","数学","英语","语文","数学","英语","语文"]

4.1.5检查序列中的成员

in运算符通常用于判断一个元素是否存在于序列中,返回的是一个bool值,这个在我们之前的成员运算符中已经介绍过了。

4.2集合类型

4.2.1认识集合

集合(Sets)是一个无序不重复元素的集。它的主要功能是自动清除重复的元素。创建集合时用大括号{ }来包含其元素。如果当我们的集合中有重复元素时,就会将其自动删除。需要注意的是,如果我们想要创建一个空集合,必须使用 set( )函数

books=set{ }  #正确创建空集合的方式
books={ }          #错误创建集合的方式

4.2.2集合类型的常见操作

  • 添加元素,添加元素的语法格式如下:
    s.add(x)
    将x元素添加到集合s中,如果元素已存在,则不进行任何操作。
  • 删除元素,删除元素的语法格式如下:
    s.remove(x)
    将元素x从集合中删除,如果元素不存在,则会报错
  • 计算元素的个数,语法格式如下:
    len(s)
    则会返回集合s的元素个数
  • 清空集合,清空集合的语法格式如下:
    s.clear( )
    通过这个操作就会将集合的元素清空。

4.3列表类型

4.3.1认识列表类型

列表是写在中括号之间,用逗号分开的元素表,类似于我们C语言中的数组。列表对象属于序数对象,是一群有序对象的集合,并且可以使用数字来作索引。列表对象可以进行新增、修改和删除的操作。这个与JavaScript中的数组属性基本上一样,可以包含不同类型的元素,但是在C语言中并不支持。同时列表对象也支持列表嵌套,即一个元素是另一个列表元素。

4.3.2列表的常见操作

  1. 获取某个元素的索引值
    使用列表对象的index©方法来返回元素的索引值,这在JavaScript中使用方法也相同

  2. 改变列表对象的元素值
    可以通过索引到列表元素然后对其进行重新赋值

  3. 删除列表中的元素
    使用del语句可以删除列表对象中的元素,例如:

    >>>x=[100,'床前明月光',8.99,4+2j]
    >>>del x[1]
    >>>x
    [100,8.99,(4+2j)]
    

    这里的删除位置同样也支持负数,比如我们要删除最后一个元素,可以直接del x[-1]

    如果我们想一次性清除所有元素,可以使用

    del a[:]
    

4.3.3列表的内置函数和方法

  1. 列表的函数
    列表内置的函数有许多,包括len( )、max( )、min( )和list( )……max和min可以直接返回列表中的最小值或最大值,但列表的元素数据类型必须一致才能使用,否则会报错。

  2. 列表的方法
    想要查看列表有哪些内置的方法时只需要在Python中输入 dir([])就可以查看到了

    • append(object)
      append()方法在列表对象的结尾,加上新对象object,这个方法与JavaScript中的push()方法相同,都是在列表结尾添加一个元素

    • clear()
      clear()方法用于清空列表,类似于del a[:]

    • copy()
      copy()方法用于复制列表,例如:

      >>>a = [100,'床前明月光',8.99]
      >>>b=a.copy()
      >>>b
      [100,'床前明月光',8.99]
      
    • count(value)

    • count(value)方法针对列表对象中的相同元素值value计算其数目。比如当我们的列表中有多个重复元素时,通过使用count()方法就可以得到列表中value的个数

    • extend(list)
      extend(list)方法将参数list列表对象中的元素加到此表中,成为此列表的新元素,也就是直接将list中的所有元素全部添加到调用者的列表中。

    • index(value)
      index(value)方法将列表对象中元素值的value的索引值返回。

    • insert(index,object)
      insert(index,object)方法将在列表对象中索引值为index的元素之前插入新元素object

    • pop([index])
      pop([index])方法将列表对象中索引值为index的元素删除。如果没有指定的index值,就将最后一个元素删除。在JavaScript中我们也有pop()方法,不过在JavaScript中一般用于删除最后一个元素,且返回值是被删除的那个元素。

    • remove(value)
      remove(value)方法将列表对象中元素值为value的删除。它与pop()方法的不同在于,pop()删除时只知道所以,但是remove()删除时只知道元素值,但不知道索引。

    • reserve()
      reverse()方法将列表对象中的元素颠倒排列。在JavaScript中也有这个方法,他们都是将列表中的元素进行颠倒。

    • sort()
      sort()方法将列表对象中的元素依照大小顺序排列。在JavaScript中也有sort()方法,但是使用方法却不同。在JavaScript中sort()方法会将数组中的字符串按照字母顺序进行升序排序,如果我们要对数字数组进行排序的话还需要去构造方法。

4.4元组类型

4.4.1认识元组

元组对象属于序数对象,是一群有序对象的集合,并且可以使用数字来作索引。元组对象与列表的对象类型,差别在于元组对象不可以新增、修改和删除,同时元组使用小括号而列表则使用中括号。

元组的创建与使用都和列表中相同,但元组是固定的,即一旦创建就无法对其进行更改。其它的属性都与列表的属性相同。

4.4.2元组的常用操作

元组的创建与列表的创建方法是相同的,但是需要注意的是如果想要创建只有一个元素的元组,那么在创建的元组之后必须要加一个逗号

>>> temp = ('我是你爸爸')
>>> type(temp)
<class 'str'>
#我们看到当不加逗号时数据类型为str,即字符串类型
>>> temp2 = ('pk哥',)
>>> type(temp2)
<class 'tuple'>
#加上逗号之后数据类型就变为元组了

之前说到元组一旦创建就是不可变的,所以我们在之后是无法在原元组上进行更改的,但是我们可以通过切片的方法以及拼接字符串的方法返回一个新元组。但是可以通过del()来删除该元组

4.4.3元组的内置函数

  1. len()函数
    len()函数返回元组的长度
  2. max()和min()函数
    max()函数返回元组或列表中元素的最大值,min()函数返回元组或列表中的最小值,需要注意的是在使用这两个函数时,元组或列表中的元素必须是同一类型时才可以,否则会报错。
  3. sum()函数
    sum()函数返回的是元组中所有元素的和

4.5字典类型

4.5.1 认识字典类型

字典类型在Python中充当着非常重要的作用,但是学过JavaScript的我看着字典这个类型总是十分亲切,因为这个类型与JavaScript中的对象是非常相似的。它们都以键值对的方式存在,但是JavaScript中对象前面的键是没有引号的。后来我发现Python中的对象与Json格式是完全一致的,这个可能会大大的方便python后期与数据进行交换。在同一个字典中,关键字必须互不相同,但是关键字对应的值可以相同。

4.5.2 字典的常用操作

  • 修改字典中的元组值
    只需要我们将字典中想要替换的键值对重新赋值即可

  • 删除字典中的元素
    使用del语句可以删除字典中的元素,例如:

    >>>x = {'一班':'张小明','二班':'王二狗','三班':'张小明'}
    >>>del x["三班"]
    >>>x
    {'一班':'张小明','二班':'王二狗'}
    
  • 定义字典键值对时需要注意的问题

    1. 不允许同一个键值多次出现,键是唯一的
    2. 因为字典的键值必须不可变,所以可以用数字、字符串或元组充当,列表则不行。

4.5.3字典的内置函数和方法

  1. 字典的内置函数
    ①len(dict):计算字典中元素的个数,即键值对的总数。
    ②str(dict):将字典的元素转换为可打印的字符串形式。
    ③type(variable):返回输入的变量类型,如果变量是字典,就返回字典类型。

  2. 字典的内置方法

    1. clear(): 清除字典中的所有元素。

    2. copy():复制字典的所有内容。

    3. get(k,default=None) :k是字典的索引值。如果k存在,就返回其值,否则,返回后面的内容。另外需要注意的是如果字典中嵌套的有另外的字典那么则无法用get直接获取value值例如:

      >>>x={'一班':'朱小明','二班':'王明霞'}
      >>>x.get("一班")
      '朱小明'
      >>>x.get("三班","不存在")
      '不存在'
      
    4. items() :使用字典中的元素创建一个由元组对象组成的列表。

    5. keys() :使用字典中的键值创建一个列表对象。也就是将字典中的所有键值存入一个新的列表中。

    6. popitem():删除字典中的最后一个元素。也就是将字典中的最后一个键值对删除,它的返回值是被删除的键值对。Python和其它语言中,如果看到pop或者是其它的一些删除的函数,我们就需要注意它的返回值,返回值一般是被删除的元素。

我们在这里需要注意以下列表和元组的区别以及列表与元组直接的相互转换,还有集合和列表的不同之处。

第五章 字符串与正则表达式

5.1字符串的常用操作

5.1.1字符串拼接

字符串的重要性不言而喻,在之前学习JavaScript的过程中也有很多字符串的相关问题。在Python中,字符串的作用也非常大,因此需要不断地总结和学习。首先是字符串拼接,使用加号(+)运算符可以将两个字符串拼接起来,成为一个新的字符串。使用方法很简单,我们之前在java和JavaScript中都有接触到字符串的拼接,但是在这里字符串的拼接需要注意的是两者类型必须都是字符串,否则会报错,如果需要将字符串和其它类型的拼接在一起的话则需要对其它类型的变量进行强制类型转换,使用str()函数,让其成为字符串,然后再进行相加。

5.1.2计算字符串的长度

在Python语言中,数字、英文、小数点、下划线和空格各占1个字节。汉字可能会占2~4个字节,占几字节屈居用采用的编码格式。由于Python语言默认采用UTF-8编码,所以汉字占有3个字节。Python语言通过len( )函数计算字符串的长度,len( )在计算字符串长度时,并不区英文和中文,统统按照一个字符进行计算。如果用户需要获取字符串的实际所占字节数,就需要指定编码。然后才能获取实际的长度。

>>>s1="我今天需要参加English考试。"  #包含了英文、中文和标点符号的字符串。
>>>ls=len(s1)       #定义字符串的长度
>>> ls
17
#--------------------------
>>>s1="我今天需要参加English考试。"  #包含了英文、中文和标点符号的字符串。
>>>ls=len(s1.encode())       #定义字符串的长度
>>> ls
37

在上面这段代码中,字符串共有9个汉字和一个中文标点符号,占30个字节,英文共有7个,所以结果为37。

5.1.3截取字符串

与列表一样,索引都是从0开始。Python访问子字符串变量,可以使用中括号([])和冒号(:)来截取字符串。使用方法 : a[x,y]

截取的字符串从x索引位置开始,到y结束,它的范围为左闭右开,即[x,y)。如果没有x则代表从0开始,如果没有y,则代表从x开始,到结尾,如果想要截取字符串全部,则x和y都不用给值,者在之前的del中就用到过。

5.1.4 分割和合并字符串

1.在Python语言中,通过split( )方法通过指定分隔符对字符串进行分割(切片),该方法的语法格式如下:

str.split(str="",num=string.count(str))

在JavaScript中也有split( )函数,它的第一个参数是一个分隔符或者是正则表达式,第二个参数表示分割后的数组的最大长度。本质上来说与python中的split效果是一样的。都是对字符串进行分割操作。

2.合并字符串

join( )方法用于将序列中的元素以指定的字符合并生成一个新的字符串,需要注意的是被合并的元素必须是字符串。

>>>s1="*"
>>>e1=('不','破','楼','兰','终','不','还')
>>>print(s1.join(e1))
不*破*楼*兰*终*不*还

5.1.5检索字符串

  1. count( )方法用于统计字符串里某个字符出现的次数,可选参数为在字符串检索的开始与结束位置。 语法格式:str.count(sub,strart=0,end=len(string)),如果缺少则默认是整个字符串。
  2. find( )方法
    find( )方法检索字符串中是否包含子字符串。如果包含该子字符串,就返回该字符串开始的索引值,否则就返回-1。这与JavaScript中的indexOf方法类似,都是检测字串是否在该字符串中,并返回第一次出现的位置。find( )方法同样也支持检索参数,即开始的位置到截至的位置索引,与前面的使用方法相同,范围也都是左闭右开。
  3. index( )方法
    index( )方法用于尖子字符串中是否包含子字符串,如果包含则返回开始位置的索引,否则就会报错。这个方法同样也支持开始的查询位置和截至的位置。

5.1.6字母的大小写转换

在Python中字符串的大小写转换函数是upper( )和low( ),使用方法与JavaScript中的toLowerCase( )和toUpperCase( )的方法相同,所以在这里不做过多解释

5.1.7删除字符串中的空格和特殊字符

  1. strip( )方法
    strip( )方法用于删除字符串头尾指定的字符或字符序列。需要注意的是该方法只能删除开头或结尾的字符,不能删除中间的字符。使用方法:str.strip([chars]),参数chars是需要删除的字符序列,默认情况下是空格。该方法的返回值为删除指定字符后生成的新字符串。

    >>>str="*****茅檐**低小**,溪上青青草。*****"
    >>>print(str.strip('*'))         #会删除开头和结尾的'*'.
    '茅檐**低小**,溪上草青青。'
    
  2. lstrip( )方法
    lstrip( )方法用于截掉字符串左边的空格或指定字符。如果未指定参数,则默认情况下是空格。这个就相当于strip( )的缩小版,只会删除字符串左边的字符。

  3. rstrip( )方法
    通过名字我们也可以看出,这个方法是以 ‘r’ 开头的,所以会删除字符串末尾的指定字符,默认情况下是空格。

5.1.8使用Python的转义字符

有时候需要在字符串内设置单引号、双引号、换行符等,在此时就可以使用转义字符。Python的转义字符是由一个反斜杠()和一个字符组成

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8S8Yiiqt-1619075310151)(C:\Users\86134\AppData\Roaming\Typora\typora-user-images\image-20210402231633558.png)]](https://img-blog.csdnimg.cn/img_convert/c0769076fee50a3e378b0c67b0833d08.png#pic_cente

换行符,\n与我们在C语言中的使用方法相同,在双引号中直接输入就可实现换行。如果要输出双引号,则直接在双引号之前加上反斜杠() 就可以实现。各进制同样也可以使用。

5.2字符串的编码转换

在Python中,有两种常用的字符串类型,分别为str和bytes。其中,str表示Unicode字符;bytes表示二进制数。这两种类型的字符不能拼接在一起使用。一个字符对应若干个字节。如果在网上上传输或者保存在磁盘上,就需要把str转换成bytes类型,即字节型

str类型和bytes类型之间可以通过encode( )和decode( )方法进行转换,这两个方法的转换是可逆的。

#coding:utf-8
s = "你好,中国!"
print(s)     # Python2输出乱码,Python3正常输出
print(type(s))    # 均输出 <type 'str'>#解码成unicode
s1 = s.decode("utf-8")
print(s1)    # Python2中输出 “你好,中国!”,Python3显示'str'对象没有属性'decode'
print(type(s1))   # Python2中输出 <type 'unicode'>  Python3中输出 <class 'str'> #编码成gbk 或 utf-8
s2 = s1.encode('gbk')
print(s2)      # Python2中输出 “你好,中国!”
print(type(s2))    # Python2中输出 <type 'str'>
s3 = s1.encode('utf-8')
print(s3)      # Python2输出乱码,
print(type(s3))    # 输出 <type 'str'>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mLJ13SMq-1619075310156)(C:\Users\86134\AppData\Roaming\Typora\typora-user-images\image-20210402233012990.png)]

5.3正则表达式和re模块

正则表达式是字符串,它包含文本和特殊字符。re模块可以执行正则表达式的功能。文字与特定字符的混合,可以定义复杂的字符串匹配与取代功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rsjqv6BC-1619075310159)(D:\qq下载\MobileFile\qq_pic_merged_1617410899232.jpg)]

字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,‘n’ 匹配字符 “n”。’\n’ 匹配一个换行符。序列 ‘\’ 匹配 “” 而 “(” 则匹配 “(”。
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 或 “does” 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。
. 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用象 ‘[.\n]’ 的模式。
(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘(’ 或 ‘)’。
(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,‘Windows (?=95|98|NT|2000)’ 能匹配 “Windows 2000” 中的 “Windows” ,但不能匹配 “Windows 3.1” 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如’Windows (?!95|98|NT|2000)’ 能匹配 “Windows 3.1” 中的 “Windows”,但不能匹配 “Windows 2000” 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
x|y 匹配 x 或 y。例如,‘z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,’[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,’[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\cx 匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。
\W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,’\x41’ 匹配 “A”。’\x041’ 则等价于 ‘\x04’ & “1”。正则表达式中可以使用 ASCII 编码。.
\num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1’ 匹配两个连续的相同字符。
\n 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
\nm 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
\nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
\un 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。

5.3.2re模块的方法

re模块的主要功能是通过正则表达式来操作字符串。在使用re模块时,需要先引入re包。即 import re。

re模块中常见操作字符串的方法:

  1. 匹配字符串
    通过re模块的match( )、search( )和findall( )方法可以匹配字符串。
    ①match( )。
    match( )方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回Match对象;如果不是在起始位置匹配成功,则返回None。match( ) 的语法格式为:

    re.match(pattern,string,flags=0)
    

    第一个参数为匹配的正则表达式,第二个参数为需要匹配的字符串,第三个参数哟关于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等。例如我们要检验输入的手机号是否为中国移动的手机号:

    第一个参数为匹配的正则表达式,第二个参数为需要匹配的字符串,第三个参数哟关于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等。例如我们要检验输入的手机号是否为中国移动的手机号:

    import re
    print("欢迎进入中国移动电话号码验证系统")
    s1=r'(13[4-9]\d{8})$|(15[01289]\d{8}$)'
    s2=input("请输入需要验证的电话号码:")
    match=re.match(s1,s2)
    if match==None:print("您输入的号码不是中国移动的号码")
    else:print("您输入的号码是中国移动的号码")
    

    ②search( )
    search( )方法用于扫描整个字符串并返回第一个成功的匹配。参数与match的参数意义相同。但与match( )不同的是,search( )方法既可以在起始位置匹配,也可以不在起始位置匹配。
    需要注意的是match( )方法只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而search( )方法匹配整个字符串,直到找到一个匹配项。

    ③findall( )
    findall( )方法用于在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配项,则返回空列表。match( )和search( )只匹配一次,而findall( )方法匹配所有。findall( )语法格式:

    findall(sting[,pos[,endpos]])
    

    参数中string是待匹配的字符串,pos为可选参数,指定字符串的起始位置,默认为0;endpos为可选参数,指定字符串的结束位置,默认为字符串的长度。

  2. 替换字符串
    通过re模块中的sub( )方法可以替换字符串中的匹配项。语法格式如下:

    re.sub(pattern,repl,string,count=0,flags=0)
    

    参数中pattern是正则表达式中的模式字符串;repl是要替换的字符串,也可以为一个函数;参数string要被查找替换的原始字符串;参数count是模式匹配后替换的最大次数,默认为0。

  3. 分割字符串
    通过re模块中的split( )方法可以分割字符串。split( )方法按照能够匹配的子串将字符串分割后返回列表。语法格式如下:

    re.split(pattern,string[,maxsplit=0,flags=0])
    

    参数中pattern是正则表达式中的模式字符串;参数string为要被分割的字符串;参数maxsplit是分割次数,默认为0,不限制次数;参数flags用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。

    import re
    s1="*张三丰*欧阳修*李白*颜真卿*齐白石"
    pattern = r'\*'
    ls = re.split(pattern,s1)  #以*分割字符串
    print("您的标星好友是:")
    for(im in ls):if im!=" ":print(im)
    

5.4格式化字符串

Python语言支持格式化字符串的输出。字符串格式化使用字符串操作符百分号(%)来实现。在百分号左侧放一个代格式化的字符串(格式化字符串),右侧放置希望被格式化的值。可以使用一个值,如一个字符串或数字,也可以使用多个值的元组或字典。

age = 18
print("赵日天已经%d岁了!" % age)
#运行结果:
赵日天已经18岁了!

当然,格式化字符串也可以包含多个转换说明符,这个时候需要提供多个表达式,用以替换对应的转换说明符;多个表达式必须使用小括号( )括起来

name = "赵日天"
age = 18
url = "http://zx529.xyz"
print("%s已经%d岁了,它的网址是%s。" % (name, age, url))
#运行结果是:
赵日天已经18岁了,它的网址是http://zx529.xyz

下面的表中列举出Python语言中字符串格式化符号

其实在这里的格式化字符串与我们在C语言中学的比较接近,同时Python还支持指定最小输出宽度以及指定对齐方式、指定小数精度。

①指定最小输出宽度:

n = 1234567
print("n(10):%10d." % n)
print("n(5):%5d." % n)url = "http://c.biancheng.net/python/"
print("url(35):%35s." % url)
print("url(20):%20s." % url)

使用表中的转换说明符,可以按照上面的格式指定最小输出宽度 。其中%10d表示输出的整数宽度至少为10.%20s 则表示输出的字符串宽度至少为20

②按照指定的小数精度输出:

f = 3.141592653
# 最小宽度为8,小数点后保留3位
print("%8.3f" % f)
# 最小宽度为8,小数点后保留3位,左边补0
print("%08.3f" % f)
# 最小宽度为8,小数点后保留3位,左边补0,带符号
print("%+08.3f" % f)
#输出的结果:3.142
0003.142
+003.142

③在Python中可以指定对齐方式。
在默认情况下,print( )输出的数据总是右对齐的。也就是说,当数据的长度不够时,它总是右边对齐,而在左边补充空格来达到指定的宽度。Python允许在最小宽度之前增加一个标志来改变对齐方式,Python支持的标志如下:

整数、小数以及字符串的对齐方式是有区别的。必须要在不改变他们大小以及有意义的前提下进行对齐。对于整数,指定左对齐时,在右边补0是没有效果的,因为会改变它的大小;对于小数,以上三个标志可以同时存在;对于字符串,则只能使用 - 因为符号对于字符串没有意义,而补0则会改变字符串的值。代码举例如下:

n = 123456
# %09d 表示最小宽度为9,左边补0
print("n(09):%09d" % n)
# %+9d 表示最小宽度为9,带上符号
print("n(+9):%+9d" % n)f = 140.5
# %-+010f 表示最小宽度为10,左对齐,带上符号
print("f(-+0):%-+010f" % f)s = "Hello"
# %-10s 表示最小宽度为10,左对齐
print("s(-10):%-10s." % s)
#运行结果为:
n(09):000123456
n(+9):  +123456
f(-+0):+140.500000
s(-10):Hello

第六章 函数

6.1 创建和调用函数

6.1.1 创建函数

在Python语言中,函数的创建需要使用def关键字,具体语法如下:

def 函数名称(参数1,参数2,……):"文件字符串"<语句>

Python语言的函数创建与我们之前在JavaScript中所学到的方法是一致的。def用于声明函数的创建,任何传入的参数和自变量必须放在小括号中间,小括号之间可以用于定于参数。函数的第一行语句可以选择性地使用文档字符串,用于存放函数说明。整体来说,Python的函数与JavaScript中的函数还是很相似的。

6.1.2 调用函数

说起函数创建,它自然离不开函数的调用。先前一步的函数创建就是为了之后的函数调用准备。函数的调用与其它语言类似,直接使用函数名进行调用。但是在Python语言中,我们可以先将函数名称设置为变量,然后使用该变量运行函数的功能。例如:

>>>x= int
>>>x(3.1415926)
3

从结果中就可以看出,int( )函数是Python语言程序的内置函数,这里直接将函数名称设置为变量x,通过变量x即可直接运行该函数。

6.2 参数传递

6.2.1 形参与实参

形参指的是在函数定义时出现的参数,可以被看作是一个占位符,它没有实际数据,只能等到函数被调用时接受传递进来的数据。
实参则指的是函数在被调用时,被传递进来的参数,是有实际数据的,即在内存中是开辟了地址的。

6.2.2 形参和实参的特点

形参变量只有在函数被调用时参会分配内存,调用结束后立刻释放内存,所以形参变量只在函数内部有效,不能在函数外部使用。而实参在使用时必须要有确定的值,可以是常量、表达式、函数等 。形参和实参在形式和数量以及顺序上必须一致,否则会发生类型不匹配的错误。

6.2.3 值传递和引用传递

参数的传递也分为两种,一种是值传递,另一种是引用传递,也可以理解为地址传递。它们之间的区别是,进行值传递后,如果改变形式参数的值,实参的值不变;进行引用传递后,如果改变形参的值,实参的值也会随着改变。而python中对一个函数可以传递参数,但是如何分辨是值传递还是引用传递,不是程序员手动控制的,而是python根据你传入的数据对象,自动识别的。
如果你传入的参数对象是可变对象:列表,字典,这个时候就是引用传递,如果参数在函数体内被修改,那么源对象也会被修改。
如果你传入的参数对象是不可变的对象:数字,元组,字符串,这个时候就是值传递。那么源对象是不会改变的。下面举例子说明:

import sys
a=2
b=[1,2,3]
def change(x,y):x=3y[0]=4
change(a,b)
print a,b
#输出结果是     2 [4, 2, 3]

可以看出数字作为一个不可变对象,a的值没有变化,而b作为列表对象,是可变对象,所以b被改变了。

import sys
a="11111"
b={"a":1,"b":2,"c":3}
def change(x,y):x="222"y["a"]=4
change(a,b)
print a,b
#输出结果是    11111 {'a': 4, 'c': 3, 'b': 2}

因为a作为字符串是不可变对象,所以没变化,b作为字典,是可变对象,所以被改变了

import sys
a=(1,2,3)
b={"a":1,"b":2,"c":3}
def change(x,y):x="222"y["a"]=4
change(a,b)
print a,b
#输出结果是  (1, 2, 3) {'a': 4, 'c': 3, 'b': 2}

6.2.4 关键字参数

Python中用户可以直接设置参数的名称及其默认值,这种类型的参数属于关键字参数。在设置函数的参数时,可以不按照它们的位置排列顺序,因为Python解释器能够用参数名匹配

fruits("苹果",12.6)      #按照参数传入顺序传入
fruits(x="苹果",y=12.6)       #按照参数传入顺序,并指定参数名
fruits(y=12.6,x="苹果")           #不按照参数顺序传入参数,并指定参数名

以上这三种方法在Python中都是允许的。

6.2.5 默认参数

调用参数时,若没有传入参数,则会抛出异常。但是可以为参数设置默认值来解决这个问题。例如:

def ns( name,score=660):     #设置score的参数默认值为660
print("姓名:",name)
print("高考总分:",score)
returnns(name="赵日天",score=586)      #传递参数,不使用默认值
ns(name="雷军")               #没有传递参数,就会使用默认值""""""程序运行结果如下
姓名: 赵日天
高考总分:586
姓名:雷军
高考总分:660

通过这里例子中可以看到当我们不传入参数时,它就会使用在定义函数时设定的默认参数。如果想要查看当前参数的默认值,可以使用函数名 .defaults 来查看函数参数的当前值,其结果是一个元组。

6.2.6 可变参数

如果用户在定义函数时不能确定需要定义几个参数时就可以使用可变参数。下面通过举例子说明

def get_sum(*numbers): sum = 0 for n in numbers: sum += n return sum print (get_sum(1,2,3,4,5))
#程序运行结果为   15

加了星号(*)的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数,那么它就是一个空元组。用户也可以不向函数传递未命名的变量。同样的用户也可以为参数设置 ** 类型的变量,即两个星号,两个星号代表的是字典对象

6.3 返回值

return 语句用于退出函数,有选择性地向调用者返回一个表达式。不带参数值的return 语句返回None 函数的返回值也可以是多个,那么此时就会以元组对象的类型返回。若函数没有返回值,则返回None。

6.4 变量作用域

在Python语言中,变量并不是在哪个位置都可以访问。变量的访问权限决定了这个变量在哪里赋值,而变量的作用域决定了该变量在哪一部分程序可以访问哪个特定的变量名称
变量的作用域包括全局变量和局部变量。其中,定义在函数内部的变量拥有一个局部作用域,定义在函数外部的则拥有全局作用域。如果要在函数内改变全局变量的值,则就要使用global关键字。

6.5 匿名函数

匿名函数,即是不使用def关键字来声明函数。Python语言中,使用lambda创建一个匿名函数。

def f(x,y)
return x-y#使用匿名函数
f=lambda x,y:x-y

匿名函数与我们在JavaScript中所学到的箭头函数形式还是很相似的,在使用时两者可以进行参考。
匿名函数在使用时也有许多要注意的地方:
①如果只有一个表达式,则必须有返回值
②可以没有参数,也可以有一个或多个参数
③不能有return

在 lambda语句中,冒号前是参数(可以有多个),用逗号隔开冒号右边的返回值。lambda语句构建的其实是一个函数对象。例如:

import math
r = float(input("请输入圆的半径:"))
area =lambda r:math.pi*r*r
print(area(r))
#程序运行结果为
请输入圆的半径:12.5
490.8738521234052

第七章 面向对象程序设计

7.1 认识面向对象

对象是类的实例化。对象分为静态特征和动态特征两种。静态特征指的是对象的外观、性质、属性等。动态特征则指的是对象具有的功能。在我们之前学习java时基本上都是面向对象编程。所以在这里就很好理解了。对象基本上可以理解为相关变量和方法的软件集。对象主要由两部分组成,一组包含各种类型数据的属性,对属性中的数据进行相关操作的相关方法。
由于Python语言时面向对象的语言,所以再Python语言中,一切都是对象,包括字符串、函数等都是对象。
面向对象中常用的技术术语如下:

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • **类变量:**类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • **数据成员:**类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
  • **方法重写:**如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • **局部变量:**定义在方法中的变量,只作用于当前实例的类。
  • **实例变量:**在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
  • **继承:**即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • **实例化:**创建一个类的实例,类的具体对象。
  • **方法:**类中定义的函数。
  • **对象:**通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

面向对象的三大特点:封装性、继承性、多态性

7.2 定义类

之前我们已经介绍过类是什么。这一步我们将介绍如何定义一个类。类是一个用户定义类型,与大多数计算机语言一样。Python语言使用关键字class来定义类,类的帮助信息可以通过ClassName.__doc__查看。
定义类的语法格式入下:

class <ClassName>:'类的帮助信息'       #类文档字符串
class_suite          #类体

下面我们直接定义一个学生类来帮助大家理解:

class Students:"这是一个定义学生类的例子"name="赵日天"def disStudents():print("这个学生类的名字是:"+name)

其中类名称为Students。name是一个类变量,它的值将在这个类的所有例之间共享。用户可以在内部类或者外部类使用Students.name来进行访问。disStudents是此类的方法,属于方法对象。

7.3 类的构造方法和内置属性

7.3.1 构造方法

构造方法是指创建对象时其本身所运行的函数。Python语言使用 init() 函数作为对象的构造方法。当用户要在对象内指向对象本身时,可以使用self关键字,这与JavaScript以及Java中的this关键字一样,都是代表对象本身。def init(self)语句定义Goods类的构造方法,self时必要的参数且为第一个参数。用户可以在里面加入许多参数,在创建类时同时设置类的属性值。

#类定义
class Goods:#定义基本属性name = ' 'factory= ' '#定义私有属性,私有属性在类外部无法直接进行访问__price= 0#定义构造方法def __init__(self,n,f,p):self.name = nself.factory = fself.__price = pdef disGoods (self):print("%s生产的%s质量非常不错。最新款的价格是%s元。" %( self. factory,self.name, self.__price))# 实例化类
g = Goods ('小米11pro','小米',5557)
g.disGoods()

7.3.2 内置属性

所有的Python都具有下面的内置属性

  1. classname.dict :l类的属性是以字典对象的方式存储的。_dict _属性为盖子点对象的值
  2. classname._doc _:_doc _属性返回此类的文件夹字符串。
  3. classname. name : _name _属性返回的时此类的名称。
  4. classname.module: _module_属性返回包含此类的模块名称

7.4 类例

7.4.1 创建类例

要创建一个类例,只需要指定变量与类名即可。使用id( )内置函数,可以返回类的识别码;使用type( )内置函数,额可以返回类的对象类型。下面我们通过创建一个简单类,并设置类的三个属性:

class Goods:def __init__(self, name=None, factory =None, price= None):self.name = nameself.factory = factoryself.price = price#创建一个类的实例变量
g = Goods ("小米11pro", "小米", 5860)
print(g.name, g.factory, g.price)
d = Goods("小米汽车", "小米", 188600)
print(d.name, d.factory, d.price)

在这个类的构造方法中,设置name、factoort与price的默认值均为None。
在创建类的时候,可以不必声明属性。等到创建类的实例后,在动态创建类的属性。例如:

>>> classs myGoods:pass
>>> x = myGoods()
x.name="电脑"

如果想测试一个类例 y 是否是类 x 的例,可以使用内置函数instance( y,x)。这与JavaScript中的instanceof作用一样,都是测试前者是否是后者的实例化对象,返回值是一个Boolean值。
用户也可以在类内定义类变量,同时这些类变量可以被所有该类的例变量所共享。下面创建一个类,并定义类变量

>>> class Vegetables:default_price = 3.66def _init _(self):self.price = Vegetables.default_price     #例变量的变量

7.4.2 类例的内置属性

所有的Python语言程序的类例都具有下面内置属性

  1. obj._ dict_:类例内的属性是以字典对象的方式存储的。

  2. obj._class _: _class _属性返回创建此类例所用的类名称

    >>>class Goods:def _init_(self,name=None,city=None,price=None):self.name = nameself.city = cityself.price = price
    >>> g = Goods()
    >>> g._dict_
    {'name':None,'city':None,'price':None}
    >>> g._class_
    <class '_main_.Goods'
    

7.5 类的继承

类的继承就是新类继承旧类的属性与方法,这种行为称为派生子类。继承的新类称为派生类,被继承的旧类则称为基类。当用户创建派生类后,就可以在派生类内新增或改写基类的任何方法。这里的继承与Java中的继承类似,但是语句却略有不同。

class <类名称> [(基类1,基类2,……)]:["文件字符串"]
<语句>

一个派生类可同时继承自多个基类,即一个子类可以同时有多个父类,基类直接用逗号(,)隔开。下面举例说明:

先定义一个基类:

class Cars:def __init__(self, name, price, city):self.name = nameself.price = priceself.city = citydef printData(self):print ("名称: ", self.name)print ("价格: ", self.price)print ("产地: ", self. city)

下面创建一个Cars类的派生类:

class bk(Cars):
def _init_(self,name,price,city):     #派生类的构造方法
Cars_init_(self,name,price,city)     #调用基类的构造方法

下一步创建一个派生类bk的例变量,并且调用基类Cars的函数printData( )打印出数据。

>>>b=bk("别克",128000,上海)
>>> b.printData()

运行结果如图所示:

当用户在类内编写函数时,要记得类函数名称空间的搜索顺序是类的实例——>类——>基类。

类继承时同样也有多继承,下面列举出代码:

#类定义
class people:#定义基本属性name = ''age = 0#定义私有属性,私有属性在类外部无法直接进行访问__weight = 0#定义构造方法def __init__(self,n,a,w):self.name = nself.age = aself.__weight = wdef speak(self):print("%s 说: 我 %d 岁。" %(self.name,self.age))#单继承
class student(people):grade = ''def __init__(self,n,a,w,g):#调用父类的构函people.__init__(self,n,a,w)self.grade = g#覆写父类的方法def speak(self):print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))#定义类speaer
class speaker():topic = ''name = ''def __init__(self,n,t):self.name = nself.topic = tdef speak(self):print("我是%s,我是一名新来的学生,我想学的技术是:%s"%(self.name,self.topic))#多重继承
class sample(speaker,student):a =''def __init__(self,n,a,w,g,t):student.__init__(self,n,a,w,g)speaker.__init__(self,n,t)test = sample("李元",20,59,6,"大数据分析")
test.speak()   #方法名同,默认调用的是在括号中排前的父类的方法#运行结果:     我是李元,我是一名新来的学生,我想学的技术是: 大数据分析

7.6 类的多态

所谓多态,就是指类可以有多个名称相同、参数类型却不同的函数。Python中给并没有明显的多态特性,因为Python函数的参数不必声明数据类型。但是Python利用动态数据类型仍然可以处理对象的多态。
因为是动态数据类型,所以Python必须等到运行该函数时,才能知道该函数的类型,这种特性称为运行期绑定。像C++以及Java语言允许类内有多个名称相同、参数却不同的函数存在。但是在Python语言中却不允许这样做,如果用户在Python的类内声明多个名称相同、参数却不同的函数,那么Python语言程序会使用类内最后一个声明的函数。要解决这个问题必须使用下面的方法,即我们之前学到的可变参数。代码如下:

class myClass:def _init_(self):passdef handle(self,*arg):if len(arg)==1:self.handle1(*arg)elif len(arg)==2:self.handle2(*arg)elif len(arg)==3self.handle3(*arg)else:print("Wrong arguments")def handle(self,x):print("1 arguments")def handle2(self,x,y):print("2 arguments")def handle3(self,x,y,z):print("3 arguments")>>> x=myClass()>>>x.handle()Wrong arguments>>>x.handle(1)1 arguments>>>x.handle(1,2)2 arguments>>>x.handle(1,2,3)3 arguments>>>x.handle(1,2,3,4)Wrong argument

7.7 类的封装

类的封装是指将其属性(变量与方法)封装在该类内,只有该类中的成员,才可以使用该类中的其它成员。这种被封装的变量与方法,称为该类的私有变量与私有方法。Python语言中所有变量与方法都是公用的。只要知道该类的名称与该变量或方法的名称,任何外部对象都可以直接存取类中的属性与方法。
要做到类的封装,必须做到以下几点:
① 如果属性名称的第一个字符是下划线,那么该属性视为类的内部变量,外边的变量不可以引用该变量。
②如果属性名称前两个字符都是单下划线,那么在编译时属性名称_arrtibuteName会被改成 _className _attributeName,className是该类的名称。由于属性名称之前加上了类的名称,因此与类中原有的属性名称有差异。

以上两个原则只是作为参考,Python语言程序类中的所有属性仍然是公用的,只要知道类与属性的名称,就可以存取类中的所有属性。

7.8 Python的优势——垃圾回收机制

Python使用了引用计数这一简单技术来跟踪和回收垃圾。在Python内部有一个跟踪变量,记录着所有使用中的对象各有多少引用,称为一个引用计数器。

当对象被创建时,就同时创建了一个引用计数。当这个对象不再需要,其引用计数变为0 时,就被垃圾回收了。但回收不是"立即"的,而是由解释器在适当的时机将垃圾对象占用的内存空间回收。例如:

class Vegetables:def __init__( self, name="西红四", price=6.88):self.name = nameself. price = pricedef __del__(self):class_name = self.__class__.__name__print (class_name, "销毁对象")v= Vegetables ()
g = v
s= v
print (id(v), id(g), id(s))    # 打印对象的id
del v
del g
del s
# 运行结果     1838495355848   1838495355848  1838495355848
#                       Vegetables 销毁对象

第八章 模块和包

8.1 模块概述

在Python中,模块是一个扩展名为 .py 的文件。
将实现某一特定功能的代码放置在一个文件夹中可以作为一个模块,从而方便其他程序直接调用。同时,使用模块还可以避免函数名和变量名冲突的问题。例如,下面代码的功能是检查敏感字,将代码保存在savestring.py,则该文件就是一个模块。

def savestring(s):
import re
print("欢迎进入敏感字过滤系统")
s1 = r'(渗透)|(攻击)|(脚本)'    #模式字符串
match = re.match(s1,s)       #进行模式匹配
if match==None:print("您输入的文字安全通过!")
else:print("警告!您输入的文字存在敏感字,请重新整理后输入!")

8.2 自定义模块

自定义的模块不仅可以规范代码,还可以方便其它程序直接调用,从而提高开发效率。

8.2.1 创建模块

将模块中的代码编写在一个单独的文件中,然后将其命名为模块名.py 即可。 需要注意的是模块名不能和标准模块重名,如果出现重名的问题,在导入标准模块时就会把这些定义的文件当成模板来加载,通常会引起错误。比如说我们下面新建一个文件名为friends.py的模块:

def makeFriends( par ):print "Hello : ", par,"My name is 赵日天, I want to make friends with you!"return

8.2.2 使用import 语句导入模块

模块创建完毕之后,就可以在其它程序中使用该模块了。导入模块可以通过import 语句来实现。

import  modulename [as alias]

modulename为导入的模块名称;[as alias ]为给模块起的别名,可以省略。现在我们就可以直接导入上面的模块 ,并且使用其中的函数。我们也可以导入其具体的一个函数,使用from……import……语句进行。这一点类似于Java中的import,比如我们要导入某一个具体的函数,但是完全可以将整个包导入,或者是直接 *,虽然结果都一样,但是个人的习惯因人而异。

import frieds
#也可以导入具体的函数
#from makeFriends import friends
friends.makeFriends("赵日地")
#打印结果为    Hello: 赵日地,My name is 赵日天 ,I want to make friends with you!

上面我们创建的后缀为py的文件我们就直接将它当作包的名字导入,然后就可以直接使用其中的函数。当解释器遇到import时,会在当前路径下搜索该模块。需要注意的是在调用模块中的变量、函数或类时,需要在变量名、函数名或者类的前面添加模块名称作为前缀。同样的,使用一个import语句可以一次加载多个模块,模块名称之间可以逗号隔开。

8.2.3 查找模块

当import有一个模块时,如果我们想要查找到一个模块的位置有三种方法,我们以hello.py为例:

  1. 在当前目录中查找hello.py模块

  2. 若没有找到,则继续从环境变脸PYTHNONPATH中查找

  3. 若没有PYTHONPATH变量,则可以到安装目录中进行查找。实际上要查找目录的信息存放到sys模块的path变量,可以打印该变量来查看Python的查找目录。可以在命令窗口进行查找

    import sys
    sys.path
    

8.2 包

8.2.1 Python 中的包

包是一组模块的集合,而模块是一个Python文件,所以包就可以理解为存放着若干个模块的集合。并且在该目录下有一个_init _.py的文件(包的初始化文件) ,可以在该文件里导入包里的所有模块。

掌握了包是什么之后,接下来学习如何定义包。定义包更简单,主要有两步:

  1. 创建一个文件夹,该文件夹的名字就是该包的包名。

  2. 在该文件夹内添加一个 init.py 文件即可。

  3. 下面定义一个非常简单的包。先新建一个 first_package 文件夹,然后在该文件夹中添加一个 init.py 文件,该文件内容如下:

    '''这是学习包的第一个示例'''
    print('this is first_package')
    

    上面的 Python 源文件非常简单,该文件开始部分的字符串是该包的说明文档,接下来是一条简单的输出语句。

    下面通过如下程序来使用该包:

    # 导入first_package包(模块)
    import first_packageprint('==========')
    print(first_package.__doc__)
    print(type(first_package))print(first_package)
    

    再次强调,包的本质就是模块,因此导入包和导入模块的语法完全相同。因此,上面程序中第 2 行代码导入了 first_package 包。程序最后三行代码输出了包的说明文档、包的类型和包本身。

    运行该程序,可以看到如下输出结果:

    这是学习包的第一个示例

    <class 'module'>
    <module 'first_package' from 'G:\\publish\\codes\\09\\9.3\\first_package\\__init__.py'>
    

    从上面的输出结果可以看出,在导入 first_package 包时,程序执行了该包所对应的文件夹下的 init.py;从倒数第二行输出可以看到,包的本质就是模块;从最后一行输出可以看到,使用 import
    first_package 导入包的本质就是加载井执行该包下的 init.py 文件,然后将整个文件内容赋值给与包同名的变量,该变量的类型是 module。

    与模块类似的是,包被导入之后,会在包目录下生成一个 pycache 文件夹,并在该文件夹内为包生成一个 init.cpython-36.pyc 文件。

    由于导入包就相当于导入该包下的 init.py 文件,因此我们完全可以在 init.py 文件中定义变量、函数、类等程序单元,但实际上往往并不会这么做。想一想原因是什么?包的主要作用是包含多个模块,因此 init.py 文件的主要作用就是导入该包内的其他模块。

    下面再定义一个更加复杂的包,在该包下将会包含多个模块,并使用 init.py 文件来加载这些模块。

    新建一个 fk_package 包,并在该包下包含三个模块文件:

    • print_shape.py
    • billing.py
    • arithmetic_chart.py

    fk_package 的文件结构如下:

    fk_package
    ┠──arithmetic_chart.py
    ┠──billing.py
    ┠──print_shape.py
    ┗━━__init__.py

    其中,arithmetic_chart.py 模块文件的内容如下:

    def print_multiple_chart(n): '打印乘法口角表的函数'    for i in range(n):       for j in range(i + 1):      print('%d * %d = %2d' % ((j + 1) , (i + 1) , (j + 1)* (i + 1)), end='  ')       print('')
    

    上面模块文件中定义了一个打印乘法口诀表的函数。

    billing.py 模块文件的内容如下:

    class Item:    '定义代表商品的Item类'   def __init__(self, price):        self.price = price    def __repr__(self):     return 'Item[price=%g]' % self.price
    

    print_shape.py 模块文件的内容如下:

    def print_blank_triangle(n):   '使用星号打印一个空心的三角形'   if n <= 0:        raise ValueError('n必须大于0')  for i in range(n):       print(' ' * (n - i - 1), end='')   print('*', end='')    if i != n - 1:         print(' ' * (2 * i - 1), end='')  else:          print('*' * (2 * i - 1), end='')    if i != 0:           print('*')       else:          print('')
    

    tk_package 包下的 init.py 文件暂时为空,不用编写任何内容。

    上面三个模块文件都位于 fk_package 包下,总共提供了两个函数和一个类。这意味着 fk_package 包(也是模块)总共包含 arithmetic_chart、 billing 和 print_shape 三个模块。在这种情况下,这三个模块就相当于 fk_package 包的成员。

    导入包内成员

    如果需要使用 arithmetic_chart、 billing 和 print_shape 这三个模块,则可以在程序中执行如下导入代码:

    # 导入fk_package包,实际上就是导入包下__init__.py文件
    import fk_package
    # 导入fk_package包下的print_shape模块,
    # 实际上就是导入fk_package目录下的print_shape.py
    import fk_package.print_shape
    # 实际上就是导入fk_package包(模块)导入print_shape模块
    from fk_package import billing
    # 导入fk_package包下的arithmetic_chart模块,
    # 实际上就是导入fk_package目录下的arithmetic_chart.py
    import fk_package.arithmetic_chartfk_package.print_shape.print_blank_triangle(5)
    im = billing.Item(4.5)
    print(im)
    fk_package.arithmetic_chart.print_multiple_chart(5)
    

    上面程序中第 2 行代码是“import fk_package”,由于导入包的本质只是加载并执行包里的 init.py 文件,因此执行这条导入语句之后,程序只能使用 fk_package 目录下的 init.py 文件中定义的程序单元。对于本例而言,由于 fk_package_init_.py 文件内容为空,因此这条导入语句没有任何作用。

    第 5 行导入语句的本质就是加载并执行 fk_package 包下的 print_shape.py 文件,并将其赋值给 fk_package.print_shape 变量。因此执行这条导入语句之后,程序可访问 fk_package\print_shape.py 文件所定义的程序单元,但需要添加 fk_package.print_shape 前缀。

    第 8 行导入语句的本质是导入 fk_package 包(也是模块)下的 billing 成员(其实是模块)。因此执行这条导入语句之后,程序可使用 fk_package\billing.py 文件定义的程序单元,而且只需要添加 billing 前缀。

    第 11 行代码与第 5 行代码的导入效果相同。

    该程序后面分别测试了 fk_package 包下的 print_shape、billing、arithmetic_chart 这三个模块的功能。运行上面程序,可以看到三个模块的功能完全可以正常显示。

    上面程序虽然可以正常运行,但此时存在两个问题:

    1. 为了调用包内模块中的程序单元,需要使用很长的前缀,这实在是太麻烦了。
    2. 包内 init.py 文件的功能完全被忽略了。

    想一想就知道,包内的 init.py 文件并不是用来定义程序单元的,而是用于导入该包内模块的成员,这样即可把模块中的成员导入变成包内成员,以后使用起来会更加方便。

    将 fk_package 包下的 init.py 文件编辑成如下形式:

    # 从当前包导入print_shape模块
    from . import print_shape
    # 从.print_shape导入所有程序单元到fk_package中
    from .print_shape import *
    # 从当前包导入billing模块
    from . import billing
    # 从.billing导入所有程序单元到fk_package中
    from .billing import *
    # 从当前包导入arithmetic_chart模块
    from . import arithmetic_chart
    # 从.arithmetic_chart导入所有程序单元到fk_package中
    from .arithmetic_chart import *
    

    该程序的代码基本上差不多,都是通过如下两行代码来处理导入的:

    # 从当前包导入print_shape模块
    from . import print_shape
    # 从.print_shape导入所有程序单元到fk_package中
    from .print_shape import *
    

    上面第一行 from…import 用于导入当前包(模块)中的 print_shape(模块),这样即可在 tk_package 中使用 print_shape 模块。但这种导入方式是将 print_shape 模块导入了 fk_package 包中,因此当其他程序使用 print_shape 内的成员时,依然需要通过 fk_package.print_shape 前缀进行调用。

    第二行导入语句用于将 print_shape 模块内的所有程序单元导入 fk_package 模块中,这样以后只要使用 fk_package.前缀就可以使用三个模块内的程序单元。例如如下程序:

    # 导入fk_package包,实际上就是导入包下__init__.py文件
    import fk_package# 直接使用fk_package前缀即可调用它所包含的模块内的程序单元。
    fk_package.print_blank_triangle(5)
    im = fk_package.Item(4.5)
    print(im)
    fk_package.print_multiple_chart(5)
    

    上面第 2 行代码是导入 tk_package 包,导入该包的本质就是导入该包下的 init.py 文件。而 init.py 文件又执行了导入,它们会把三个模块内的程序单元导入 tk_package 包中,因此程序的下面代码可使用 tk_package.前缀来访问三个模块内的程序单元。

    运行上面程序,同样可以看到正常的运行结果。

Python零基础入门相关推荐

  1. python零基础入门教程视频下载-Python零基础入门学习视频教程全42集,资源教程下载...

    课程名称 Python零基础入门学习视频教程全42集,资源教程下载 课程目录 001我和Python的第一次亲密接触 002用Python设计第一个游戏 003小插曲之变量和字符串 004改进我们的小 ...

  2. python基础教程视频教程百度云-Python零基础入门学习视频教程全42集百度云网盘下载...

    课程简介 Python零基础入门学习视频教程全42集百度云网盘下载 课程目录 042魔法方法:算术运算 041魔法方法:构造和析构 040类和对象:一些相关的BIF 039类和对象拾遗 038类和对象 ...

  3. 11岁过python1级_11岁表弟写的Python零基础入门笔记!

    一.Python输入与输出输出:使用print()函数. print()函数的基本语法格式如下:print(输出内容). 输出内容可以是数字和字符串(字符串需要用引号括起来),也可以是包含运算符的表达 ...

  4. Python零基础入门(一)——Python基础关键字和语法[学习笔记]

    Python零基础入门(一)--Python基础关键字和语法 目录 1. Hello World! 2. 字符串操作 3. 简单数学计算 4. if elif else 5. 循环 基础类型 pyth ...

  5. python基础代码大全-python零基础入门命令方式汇总大全,快速恶补你的Python基础...

    原标题:python零基础入门命令方式汇总大全,快速恶补你的Python基础 无意中浏览到这篇来自大牛的分享,总结的很全面,我重新排版下放在这里,希望能帮助到大家.在此十分感谢原作者! 在开始之前还是 ...

  6. Python入门必备,Python零基础入门

    近几年来,Python发展势头强劲,越来越多的公司加大了对Python开发人才的招聘.很多人都看好Python的发展,纷纷前来学习Python. 目前Python应用范围还是挺多的,从Web.爬虫.数 ...

  7. 视频教程-Python零基础入门教程-Python

    Python零基础入门教程 从2012年从事互联网至今有7年软件编程经验,曾任职国内北京互联网公司,中南林业大学授课Python 现任逻辑教育Python课程负责人,精通Python语言,精通人工智能 ...

  8. 【学习记录】Python零基础入门(五)

    第五章 Python零基础入门之条件.循环及其他语句 本人自学的主要教材为Magnus Lie Hetland的Beginning Python:From Novice to Professional ...

  9. python零基础入门教程(非常详细),从零基础入门到精通,看完这一篇就够了

    前言 本文罗列了了python零基础入门到精通的详细教程,内容均以知识目录的形式展开. 第一章:python基础之markdown Typora软件下载 Typora基本使用 Typora补充说明 编 ...

  10. python基础教程百度云-Python零基础入门学习视频教程全42集百度云网盘下载

    课程简介 Python零基础入门学习视频教程全42集百度云网盘下载 课程目录 042魔法方法:算术运算 041魔法方法:构造和析构 040类和对象:一些相关的BIF 039类和对象拾遗 038类和对象 ...

最新文章

  1. MyBatis-学习笔记01【01.Mybatis课程介绍及环境搭建】
  2. Mac 删除应用卸载后无法正常移除的图标
  3. JavaScript高级程序设计20.pdf
  4. net clr via c sharp chap1-- note
  5. 检测字符串包含emoji表情
  6. Python 网页编程- Pyramid 安装测试
  7. 怎样让手中的钱成为生财工具
  8. FreeSql (三十三)CodeFirst 类型映射
  9. ES5和ES6中的变量声明提升
  10. web-使用wsgiref模块模拟web框架
  11. stack java实现_java实现stack
  12. AFNetWork 学习资源....
  13. 数据结构-树的进化及与数据库的关系
  14. 结构体学生成绩输入和输出
  15. 探究CSS中border-top属性的使用
  16. 烧录软件:mcuisp和FlyMcu下载
  17. 设置无线网卡为AP工作模式(pi2和pi3)
  18. python京东预约抢购_python 脚本实现京东抢购
  19. Android自定义View,仿QQ显示用户等级
  20. Win7专业版 下安装ArcGIS desktop 9.3总结

热门文章

  1. LayoutInflater源码分析
  2. 如何为flv.js添加p2p播放功能
  3. 表格表单HTML代码学生登记,html实现用户注册页面(表单+表格)——html小练习...
  4. 2022最新每天领访客说说赞绿钻PHP单页源码
  5. 《语义网基础教程》学习笔记(二)
  6. Python|趣解身份证号码的奥秘
  7. Qt使用Q_UNUSED宏处理不使用的形参
  8. AI TIME 3 周年 | 三生万物,生生不息(文末有惊喜!)
  9. 人生苦短,我为什么要学Python?
  10. uni-app 组件找不到问题常规解决办法