Python学习笔记(待更新)

一、开发环境的搭建

  • 开发环境搭建就是安装python的解释器

    • python 的解释器分类:

      • CPython(用C语言编写的python的解释器)

      • pypy(用python语言编写的python解释器)

      • IronPython(用.net编写的Python解释器)

      • Jython(用Java编写的Python解释器)

二、基本语法

  • Python中严格区分大小写

  • Python中的每一行就是一条语句

  • Python中每一行语句不要过长

  • 一条语句可以分多行编写,语句后边以\结尾

  • Python是缩进严格的语言,所以在Python中不要随便写缩进

  • 在Python中使用#来表示注释,#后的内容都已属于注释,注释的内容将会被解释器所忽略,我们可以通过注释对程序进行解释说明。

1.字面量和变量

  • 字面量:即字面的值,程序中可以直接使用字面量;e.g. 1、2、3、4、5、6、'HELLO'

  • 变量:变量可以用来保存字面量,并且变量中的保存的字面量是不定的;e.g. a=10; a=20;

2.变量和标识符

  • 变量

    • Python中使用变量不需要声明,直接为变量赋值即可

    • 未赋值的变量不可使用

    • Python是一个动态类型的语言,可以为变量赋值任意类型的值,也可以任意修改变量的值

    • e.g. a='hello'

  • 标识符

    • 在Python中所有可以自主命名的内容都属于标识符

    • e.g. 变量名、函数名、类名

    • 标识符必须遵循标识符的规范

      • 标识符中可以包含字母、数字、下划线,但是不能以数字开头;e.g. demo_1

      • 标识符不能是Python中的关键字和保留字

      • 命名规范

        • 下划线命名法:所有字母小写,单词之间使用_分割;e.g. max_length

        • 帕斯卡命名(驼峰命名):每个单词首字符大写,其余字母小写;e.g. MaxLength

  • 数据类型

    • 数值:整数、浮点数、复数

      • 整型

        • 所有整数都是int类型,Python中的整数的大小没有限制,可以是一个无限大的整数;e.g. c=99999999999999999999

        • 如果数字的长度过大,可以使用下划线作为分隔符;e.g. c=123_456_789,打印不受影响

        • d= 0123 ;十进制的数据不能以0开头

        • 其他进制的整数,只要是数字打印时一定是以十进制的形式展示

          • 二进制 0b开头;c=0b10

          • 八进制 0o开头

          • 十六进制 0x开头

        • 也可以通过运算符来对数字进行运算,并且可以保证整数运算的精确

      • 浮点数(小数),在Python中所有的小数都是float类型

        • c=1.23

        • c=4.56

        • 对浮点数进行运算时,可能会得到一个不精确的结果

          • c=0.1+0.2 #0.30000000004

    • 字符串

      • 字符串用来表示一段文本信息,字符串是程序中使用的最多的数据类型

      • 在Python中字符串需要使用引号引起来; s='hello'

      • 引号可以是双引号,也可以是单引号,但是不能混着使用

        • s='hello'

        • s="hello"

      • 相同的引号之前不能嵌套

      • 单引号和双引号不能跨行使用(需要借助换行符\)

      • 使用三重引号来显示一个长字符串''' ''' 或""" """(支持换行)

      • 转义字符,使用\作为转义字符,通过转义字符,可以在字符串中使用一些特殊的内容

        • e.g. \t 表示制表表

        • e.g. \n 表示换行符

        • e.g. \uxxxx表示unicode编码

      • 格式化字符串

        • 字符串之间用加法,进行拼接

        • 占位符

          • %s在字符串中表示任意字符

          • %f 浮点数占位符

          • %d 整数占位数

        • 格式化字符串f

          • 在字符串前添加一个f来创建一个格式化字符串

          • f 'hello {a}{b}'

        • 字符串复制(将字符串和数字相乘)

          • a ='abc'

          • a=a*2

          • 输出为:abcabc

      • 布尔值(bool)

        • 主要用来做判断逻辑

        • 布尔值一共有两个Ture(真)和False(假)

        • 布尔值实际上也属于整型,Ture相当于1,False相当于0

      • None(空值)

        • None专门用来表示不存在

    • 数据类型检查

      • type()用来检查值的类型

3.对象(object)

  • 初步认识

    • python 是一门面向对象的语言

    • 程序运行当中,所有的数据都是存储到内存当中然后再运行

    • 对象就是内存中专门用来存储指定数据的一块区域

    • 对象实现上就是一个容器,专门用来存储数据

  • 对象的结构

    • 每个对象中都要保存三种数据

      • id(标识)

        • id用来标识对象的唯一性,第一个对象都有一个唯一的id

      • 对象的id相当于人的身份证号一样

      • 可以通过id()函数来查看对象的id

      • id是由解释器生成的,在CPython中,id就是对象的内存地址

      • id一旦创建,则它的id永远不可改变

    • type(类型)

      • 类型用来标识当前对象所属的类型

      • e.g. int , float, srt bool ...

      • 类型决定了对象哪些功能

      • Python是一门强类型的语言,对象一旦创建类型便不能修改

    • value(值)

      • 值就是对象中存储的具体的数据

      • 对于有些对象值是可以改变的

      • 对象分为两大类,可变对象/不可变对象

  • 变量与对象

    • 对象并没有直接存储到变量中,在Python中变量更像是给对象起了一个别名

    • 变量中存储的不是对象的值,而是对象的id(内存地址),当我们使用变量时,实际上就是在通过对象id在查找对象

    • 变量中保存对象(id),只有在为变量重新赋值时才会改变

    • 变量和变量之间是相互独立的,修改一个变量不会影响另外一个变量

4.类型转换与运算符

  • 类型转换

    • 所谓的类型转换,将一个类型的值对象转换为其他对象

    • 类型转换不是改变对象本身的类型,而是根据当前对象的值创建一个新对象

    • 类型转换四个函数

      • int()

      • 可以用来将其他的对象转换为整型

        • 规则

        • 布尔值:Ture -> 1 False -> 0

        • 浮点数:直接取整,省略小数点后的内容

        • 字符串:合法的整数字符串,直接转换为对应的数字;如果不是一个合法的整数字符串,则报错ValueError;

        对于其他不可转换为整型的对象,直接抛出异常ValueError

      • int() 函数不会对原来的变量产生影响,它是对象转换主指定的类型并将其作为返回值返回

      • 如果希望修改原来的变量,则需要对变量进行重新赋值

    • float()

      • 与int()基本一致,不同的是它会将对象转换为浮点数

    • str()

      • 可以将对象直接转换为字符串

    • bool()

      • 可以将对象转换为布尔值,任何对象都可以转换为布尔值

      • 规则

        • 对于所有表示空性的对象都会转换为False,其余转换为Ture

        • 哪些表示的空性:0、None、''、........

  • 运算符(操作符)

    • 运算符可以对一个值或多个值进行运算或各种操作

    • 运算符的分类

      • 算术运算符

      • 加法运算符(+), 如果是两个字符串之间的进行运算,则会进行拼串操作

      • 减法运算符(-)

      • 乘法运算符(*),如果将字符串和数据相乘,则会对字符串进行复制操作,将字符串重复指定次数

      • 除法运算符(/),运算时结果总会返回一个浮点类型

      • 整除(//),只会保留计算后的整数位,总会返回一个整型

      • 幂运算(**),求一个值的几次幂

      • 取模(%),求两个数相除的余数

    • 赋值运算符

      • = 可以将等号右侧的值赋值给等号左侧的变量

      • += - > a +=5 相当于 a =a + 5

      • -=

      • *=

      • **=

      • /=

      • //=

      • %=

    • 比较运算符(关系运算符)

      • 比较两个值之间的关系,总会返回一个布尔值,如果关系成立,返回True,否则返回False

      • 字符串进行比较时,是比较的unicode编码,逐位比较

      • ">" :比较左侧值是否大于右侧值

      • ">=":比较左侧值是否大于等于右侧值

      • "<":比较左侧值是否小于右侧值

      • "<=":比较左侧值是否小于等于右侧值

      • "==":比较两个对象的值是否相等

      • "!=":比较两个对象的值是否不相等

      • is:比较两个对象是否为同一个对象,比较的是对象的Id

      • is not :比较两个对象是否不是同一个对象,比较的是对象的id

    • 逻辑运算符

      • 逻辑运算符主要用来做一些逻辑判断

      • not 逻辑非

        • not 可以对符号右侧的值进行非运算

        • 对于布尔值,非运算会对其进行取反操作,True变False,False变True

        • 对于非布尔值,非运算会将其转换为布尔值,然后再取反

      • and 逻辑与

        • and可以对符号两侧的值进行与运算

        • 只有在符号两侧的值都为True时,都会返回True,只要有一个False就返回False

        • Python中的与运算是短路的与,第一值为False就不会再看第二个

      • or 逻辑或

        • or可以对符号两侧的值进行或运算

        • 或运算两个值中只要有一个True,就会返回True

        • Python中的或运算是短路的或,第一个值为True就不会再看第二个

      • 非布尔值的与或运算

        • 当我们对非布尔值进行与或运算时,Python会将其当做布尔值运算,最终会返回原值

        • 与运算的规则

          • 与运算是找False,如果第一个值是False,则不看第二个值

          • 如果第一个值是False,则直接返回第一个值,否则返回第二个值

        • 或运算的规则

          • 或运算是找True,如果第一个值是True,则不看第二个值

          • 如果第一个值是True,则直接返回第一个值,否则返回第二个值

    • 条件运算符(三元运算符)

      • 语法:语句1 if 条件表达式 else 语句2

      • 执行流程

        • 条件运算符在执行时,会先对条件表达式进行求值判断

          • 如果判断结果返回Ture,则执行语句1,并返回执行结果

          • 如果判断结果返回False,则执行语句2,并返回执行结果

    • 运算符的优先级

      • 运算符的优先级可以根据优先级诉表格来查询

      • 在表格中位置越靠下的运算符优先级越高,优先级越高的越优先计算

      • 如果优先级一样则自左向右计算

      • 实际使用中,如果碰到优先级不清楚的,可以通过小括号来改变运算顺序

三、流程控制语句

1.简介

  • python代码在执行时按照自上向下顺序执行的;通过流程控制语句,可以改变程序的执行顺序,也可以让指定的程序反复执行多次

  • 流程控制语句分成两大类:条件判断语句,循环语句

2.条件判断语句(if)

  • 语法:if 条件表达式 : 语句

  • 执行的流程:if语句在执行时,会先对条件表达式进行求值判断

    • 如果为True,则执行if后的语句

    • 如果为False,则不执行

3.条件判断语句(if - else)

  • 语法

    if 条件表达式 : 
        代码块
    else : 
        代码块
  • 执行流程

    • if - else 语句在执行时,先对if后的条件表达式进行求值判断

    • 如果为True,则执行if后的代码块

    • 如果为False,则执行else后的代码块

4.条件判断语句(if - elif - else)

  • 语法

    if 条件表达式:
        代码块
    elif 条件表达式:
        代码块
    elif 条件表达式:
        代码块
    elif 条件表达式:
        代码块
    else:
        代码块
  • 执行流程

    • if - elif - else 语句在执行时,会自上向下依次对条件表达式进行求值判断

    • 如果表达式的结果为True,则执行当前代码块,然后语句结束

    • 如果表达式的结果为False,则继续向下判断,直到找到True为止

    • 如果所有表达式都是False,则执行else后的代码块

    • if- elif - else中只会有一个代码块会执行

5.流程控制语句-练习

  • 练习1: 编写一个程序,获取一个用户输入的整数。然后通过程序显示这个数是奇数还是偶数

    number = int(input('请输入一个整数:'))
    if number < 0:
        print('请输入大于0的数')
    elif number == 0:
        print('0既不是可数,也不是偶数')
    else:
        if number%2 == 0:
            print(number,'是偶数')
        else:
            print(number,'是奇数')

  • 练习2:编写一个程序,检查任意一个年份是否为闰年(如果一个年份可以被4整除不能被100整除,或者可以被400整除,这个年份就是闰年)

    year = int(input('请输入一个年份:'))
    if (year%4 == 0 and year%100 != 0) or (year%400 == 0):
        print(year,'是闰年')
    else:
        print(year,'不是闰年')

  • 练习3:我家的狗5岁了,5岁的狗相当于人类的10.5岁,然后每增加一年就增加4岁;那么5岁的狗相等于人类的年龄就应该是10.5+10.5+4+4+4=33岁;编写一个程序,获取用户输入的狗的年龄,然后通过程序显示其相当于人类的年龄。如果用户输入的是一个负数,请显示一个提示信息

    human_age=0
    dog_age = int(input('请输入小狗的年龄:'))
    if dog_age <= 0:
        print('请输入一个正确的年龄(大于0):')
    else:
        if dog_age <= 2:
            print('小狗的%d相当于人类的%d岁'%(dog_age,dog_age*10.5))
        else:
            #两岁前的年龄
            human_age=10.5*2
            #两岁后的年龄
            human_age += (dog_age-2)*4 
            print('小狗的%d岁相当于人类的%d岁' %(dog_age,human_age))
    ​

  • 练习4:从键盘输入小明的期末成绩:

    • 当成绩为100时,奖励1辆BMW

    • 当成绩为[80-99]时,奖励1台iphone

    • 当成绩为[60-79]时,奖励1本参考书

    • 其他时,什么奖励也没有

      score = int(input('请输入小明的期末成绩(0~100):'))
      if 0 <= score <= 100:
          if score == 100:
              print('奖励1辆BWM')
          elif score >= 80:
              print('奖励1台iphone')
          elif score >= 60:
              print('奖励1本书!')
          else:
              print('没有任何奖励!')
      else:
          print('输入内容不合法,请重新输入')

  • 练习5:大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件

    • 高:180cm以上 ;富:1000w以上;帅:500以上;

    • 如果这三个条件同时满足,则:我一定要嫁给他

    • 如果三个条件有为真的情况,则:嫁吧,比上不足,比下有余

    • 如果三个条件都不满足,则:不嫁!

      height = int(input('请输入身高(cm):'))
      deposit = int(input('请输入存款(w):'))
      handsome = int(input('请输入帅气值:'))
      ​
      if height >= 180 and deposit >= 1000 and handsome >= 500:
          print('我一定要嫁给他。')
      elif height >= 180 or deposit >= 1000 or handsome >= 500:
          print('嫁吧,比上不足,比下有余。')
      else:
          print('不嫁,哥乌恩。')

四、循环控制语句

1.简介

  • 循环语句可以使指定的代码块重复指定的次数

  • 循环语句分为两种,while、for

2.while循环

  • 语法

while 条件表达式:
    代码块
  • 执行流程

    • while语句在执行时,会先对while后的条件表达式进行求值判断

    • 如果判断结果为True,则执行循环体(代码块)

    • 循环体执行完毕,继续对条件表达式进行求值判断,以此类推

    • 直到判断结果为False,则循环终止

3.while循环练习

  • 练习1 求100以内所有奇数之和

    i = 1
    result = 0
    while i <= 100:
        if i % 2 != 0:
            result += i
        i += 1
    print('result=', result)

  • 练习2 求100以内所有7的倍数之和,以及个数

    i = 7
    result = 0
    appearance_times = 0
    while i <= 100:
        result += i
        appearance_times += 1
        i += 7
    print('7以内的倍数=%d,7以内的个数为%d' % (result, appearance_times))

  • 练习3 求1000以内所有的水仙花数

    limit = int(input('请输入水仙花数的范围:'))
    if len(str(limit)) < 3:
        print('请重新输入,水仙花数最少是三位数!')
    else:
        i = 100
        while i < limit:
            total = 0
            flower_list = list(str(i))
            flower_len = len(flower_list)
            for f in flower_list:
                total += int(f)**flower_len
            if total == i:
                print('水仙花数:%d' % i)
            i += 1

  • 练习4 获取用户输入的任意数,判断其是否是质数

num = int(input('请输入一个数字:'))
i = 2
flag = True
while i < num:
    # 判断num是否能被i整除
    # 如果num能被i整除,那么num一定不是质数
    if num % i == 0:
        flag = False
    i += 1
if flag:
    print(num, '是质数')
else:
    print(num, '不是质数')
    
    
优化:
from time import *
i = 2
start =time()
while i <= 100000:
    # 创建一个变量,标记i的状态,默认i是质数
    flag = True
    j = 2
    # 质数不包含1和它本身,所以要j<i
    while j <= i**0.5:
        if i % j == 0:
            flag = False
            break
        j += 1
    if flag:
        print(i)
    i += 1
​
end = time()
print()
print(end-start,'秒')
  • 练习5 嵌套循环

打印图形
*
**
***
****
*****
i = 0
while i < 5:
    j = 0
    while j < 5-i:
        print('*',end='')
        j += 1
    print()
    i += 1
  • 练习6 嵌套循环

打印图形
*****
****
***
**
*
i = 0
while i < 5:
    j = 0
    while j < 5-i:
        print('*',end='')
        j += 1
    print()
    i += 1
  • 练习7 打印九九乘法表

i = 0
# 外循环控制行
while i < 9:
    i += 1
    j = 0
    #内循环控制列
    while j < i:
        j += 1
        print(f'{j}*{i}={i*j}',end='\t')
    print()
​
#输出结果:    
1*1=1   
1*2=2   2*2=4   
1*3=3   2*3=6   3*3=9   
1*4=4   2*4=8   3*4=12  4*4=16  
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25  
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  
1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64  
1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81
  • 求100以内的质数

i = 2
while i <= 100:
    # 创建一个变量,标记i的状态,默认i是质数
    flag = True
    j = 2
    # 质数不包含1和它本身,所以要j<i
    while j < i:
        if i % j == 0:
            flag = False
        j += 1
    if flag:
        print(i,end=' ')
    i += 1

4.跳出循环

  • break与continue

    • break 立即退出当前循环(包括else)

      • e.g.

      i = 0
      while i < 5:
          print(i)
          break
          i += 1
      else:
          print('循环结束')

    • continue 跳出本次循环,进行下一次循环

      • e.g.

      i = 0
      while i < 5:
          i += 1
          if i == 3:
              continue
          print(i)
          
      #输出结果:
      1
      2
      4
      5

五、数据结构-序列

1.序列(squence)

  • 序列是Python中最基本的一种结构

  • 数据结构指计算机中数据存储的方式

  • 序列用于保存一组有序的数据,所有的数据在序列当中都有一个唯一的位置(索引),并且序列中的数据会按添加顺序来分配索引

  • 序列的分类

    • 可变序列(序列中的元素可以改变)

      • 列表(List)

    • 不可变序列(序列中的元素不可改变

      • 字符串(str)

      • 元组(tuple)

  • 序列的通用操作(使用list演示)

# + 可以将两个列表拼接为一个列表
my_list = [1, 2, 3] + [4, 5, 6]
print(my_list)
​
# * 可以将列表重复指定的次数
my_list = [1, 2, 3] * 3
print(my_list)
​
# in用来检查指定元素是否存在于列表中
# 如果存在,返回True,否则返回False
print(7 in my_list)
​
# not in用来检查指定元素是否不在列表中
# 如果不存在,返回True,否则返回False
print(5 not in my_list)
print(1 not in my_list)
​
# len()获取列表中的元素的个数
# min()获取列表中的最小值
# max()获取列表中的最大值
arr = [20, 41, 96, 3, 14]
print(min(arr), max(arr))
​
'''
两个方法(method),方法和函数基本上一样,只不过方法必须通过[ 对象.方法() ]的形式调用
xxx.print() 方法实际上就是和对象关系紧密的函数
s.index() 获取指定元素在列表中的第一次出现时索引
'''
arr = [20, 41, 96, 3, 14, 55, 20, 41,20]
print(arr.index(20))
​
# index() 第二个参数,表示查找的起始位置,第三个参数表示查找的结束位置
print(arr.index(20, 2, 7))
​
# s.count() 统计指定元素在列表中出现的次数
print(arr.count(20))
​
#输出结果:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 1, 2, 3, 1, 2, 3]
False
True
False
3 96
0
6
3

2.列表(list)

  • 对象是Python中的一个对象

  • 对象(object)就是内存中专门用来存储数据的一块区域

  • 之前我们学习的对象,像数值,它只能保存一个单一的数据

  • 列表中可以保存多个有序的数据

  • 列表的使用

    • 列表的创建

      • 通过[ ]创建列表,e.g. my_list = [ ]

      • 列表存储的数据,称为元素

      • 一个列表中可以存储多个元素,也可以创建列表时,来指定列表中的元素;e.g. my_list = [10]

      • 当向列表中添加多个元素时,用逗号分隔元素;e.g. my_list =[10,20,30,40,50]

      • 列表中可以保存任意的对象

      • 列表中的对象都会按照插入的顺序存储到列表中,第一个元素对象保存到第一个位置,第二个元素保存到第二个位置

      • 通过索引(index)来获取列表中的元素,索引是元素在列表中的位置,列表中的每个元素都有一个索引

      • 索引从0开始,索引可为负数,即从尾部的开始数

      • 通过索引获取列表的数据,语法:list_name[索引]

      • 获取列表的长度,列表中元素的个数,len()函数,通过该函数可以获取列表的长度;获取到的长度的值,是列表的最大索引+1

    • 操作列表的数据

      • 切片(从现有列表中,获取一个子列表)

        • 语法:列表[起始:结束]

        • 通过切片获取元素时,会包括起始位置的元素,不会包括结束位置的元素

        • 做切片操作时,总会返回一个新的列表,不会影响原来的列表

        • 起始和结束位置的索引都可以忽略不写

        • 如果省略结束位置,则会一直截到最后

        • 如果省略起始位置,则会从第一个元素开始截取

        • 如果起始和结束位置全部省略,则相当于创建了一个列表的副本

        my_list = ['一', '二', '三', '四', '五']
        print(my_list[1:])
        print(my_list[:3])
        print(my_list[:])
        ​
        #输出结果:
        ['二', '三', '四', '五']
        ['一', '二', '三']
        ['一', '二', '三', '四', '五']
        • 语法:列表[起始:结束:步长]

        • 步长表示:每次获取元素的间隔,默认值是1

        my_list = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
        # 步长为2
        print(my_list[0:6:2])
        # 如果步长是负数,则会从列表的后部向前取元素
        # 列表做倒序操作时可用此方法
        print(my_list[::-1])
        ​
        #输出结果
        ['一', '三', '五']
        ['十', '九', '八', '七', '六', '五', '四', '三', '二', '一']
      • 通过切片修改列表中的元素(支持所有可变序列)

        ball = ['badminton', 'football', 'basketball', 'tableTennis', 'tennis', 'volleyBall']
        ​
        # 新元素替换旧元素
        print('替换前:', ball)
        ball[0:2] = ['new_badminton', 'new_football']
        print('替换后:', ball)
        ​
        ​
        # 当设置步长时,序列中的个数必须和切片中元素的个数一致
        ball = ['badminton', 'football', 'basketball', 'tableTennis', 'tennis', 'volleyBall']
        print('将要替换的元素:', ball[::2])
        ball[::2] = ['new_badminton2', 'new_basketball2', 'new_tennis2']
        print('替换后:', ball)
        ​
        ​
        # 通过切片来删除元素
        # del ball[0:2]
        # del ball[::2]
        # ball[0:2] = []
    • 列表的方法

      • append(),列表尾部添加一个元素

        • s.append(元素)

      • insert(),向列表的指定位置插入一个元素

        • s.insert(插入位置的索引,插入的元素)

      • extend(),使用新的序列来扩展当前序列,需要一个序列作为参数,它会将序列中的元素添加到当前列表中

        • s.extend(序列)

      • clear(),清空序列

      • pop(),根据索引删除并返回被删除的元素

        • s.pop(如不传参,则删除最后一个)

      • remove(),删除指定元素,如果有多个元素相同,只会删除第一个

        • s.remove(元素值)

      • reverse(),用来反转列表元素,步长改成-1也可做相同效果

      • sort(),用来对列表中的元素进行排序,默认升序排列

        • s.sort(reverse=True) -> 降序排列

    • 遍历列表

      • 通过for循环来遍历列表

      • 语法

        for 变量 in 序列:
            代码块
            
        # for循环的代码会执行多次,序列中有几个元素就会执行几次,每执行一次就会将序列中的一个元素赋值给变量,所所以我们可以通过变量,来获取列表中的元素
        for b in ball:
            print(b)
        ​
        # 输出结果:
        badminton
        football
        basketball
        tableTennis
        tennis
        volleyBall

3.练习(扩展)

print('='*20, '欢迎使用员工管理', '='*20)
​
print('''
请选择要做的操作:
\t1. 查询员工
\t2. 添加员工
\t3. 删除员工
\t4. 退出系统
''')
​
​
employees = ['\t孙悟空\t18\t\t男\t\t花果山',
             '\t猪八戒\t15\t\t男\t\t天上的某个猪圈'
             ]
​
​
while True:
    choice = input('请选择[1-4]:')
    print('=' * 55)
    # 序号会发生变化,此处初始化
    num = 1
    # 查询员信息
    if choice == '1':
        print('序号\t\t姓名\t\t年龄\t\t性别\t\t住址')
        for employee in employees:
            print(f'{num}\t{employee}')
            num += 1
​
    # 添加员工信息
    elif choice == '2':
        name = input('请输入姓名:')
        age = input('请输入年龄:')
        gender = input('请输入性别:')
        address = input('请输入住址:')
​
        # 输入内容做拼接
        info_mix = '\t' + name + '\t' + age + '\t\t' + gender + '\t\t' + address
​
        employees.append(info_mix)
​
        print('添加员工信息成功!')
​
    # 删除员工信息
    elif choice == '3':
        del_name = input('请输入要删除的员工姓名:')
        for e in range(len(employees)):
            if del_name in employees[e]:
                print(employees[e])
                del employees[e]
                break
            else:
                continue
    elif choice == '4':
        print('欢迎下次使用,谢谢!')
        break
    else:
        print('输入错误,请重新输入!')

4.range函数(扩展)

  • range()是一个函数,可以用来生成一个自然数的序列

  • 该函数需要三个参数

    • 起始位置(可以省略,默认是0)

    • 结束位置

    • 步长(可以省略,默认是1)

  • range一般结合for循环使用

    • for s in range(10):

      print(s)

5.元组

  • 说明

    • 元组是一个不可变的序列

    • 它的操作的方式基本和列表一致的

    • 在操作元组时,把元组当成为一个不可变的列表即可

    • 一般当不希望数据发生改变时,就使用元组,其余情况都使用列表

  • 创建元组

    # 创建元组
    my_tuple = ()
    ​
    # 创建及初始化
    # 当元组不是空元组时,括号可以省略
    # 如果元组不是空元组,它里边至少要有一个逗号(,)
    my_tuple = (1, 2, 3, 4, 5)
  • 解包

    # 元组的解包(解构)
    # 解包指将元组当中每一个元素都赋值给一个变量
    my_tuple = (10, 20, 30, 40)
    a, b, c, d = my_tuple
    print(a)
    print(b)
    print(c)
    print(d)
    ​
    # 交换a 和 b的值,这时可以利用元组的解包
    a,b = b,a
    ​
    # 在对一个元组进行解包时,变量的数量必须和元组中元素的数量一致
    # 也可以在变量前边加一个* ,这样变量将会获取元组中所有剩余的元素(形成一个列表)
    a , b, *c = my_tuple

6.可变对象(扩展)

  • 每个对象中都保存了三个数据

    • id 标识

    • type 类型

    • value 值

  • 列表就是一个可变对象

    a = [1,2,3]

  • a [ 0 ] = 10 (改对象)

    • 这个操作是在通过变量去修改对象的值

    • 这种操作不会改变变量所指向的对象

    • 当我们去修改对象时,如果有其他变量也指向了该对象,则修改也会在其他的变量中体现

  • a = [4,5,6] (改变量)

    • 这个操作是在给变量重新赋值

    • 这种操作会改变变量所指向的对象

    • 为一个变量重新赋值时,不会影响其他的变量

  • 一般只有在为变量赋值时才是修改变量,其余的都是修改对象

  • == 与 is

    • == != 比较的是对象的值是否相等

    • is is not 比较的是对象的id是否相等

    a = [1, 2, 3]
    b = [1, 2, 3]
    print(a,b)
    print(id(a),id(b))
    ​
    print(a == b)
    print(a is b)
    ​
    # 输出结果:
    [1, 2, 3] [1, 2, 3]
    2213956161472 2213956482304
    True
    False

六、数据结构-非序列

1.字典介绍

  • 字典属于一种新的数据结构,称为映射(mapping)

  • 字典的作用和列表类似,都是用来存储对象的容器

  • 列表存储数据的性能很好,但是查询数据的性能很差

  • 在字典中每个元素都有一个唯一的名字,通过这个唯一的名字可以快速的查找到指定的元素

  • 在字典中可以保存多个对象,每个对象都会有一个唯一的名字

    • 这个唯一的名字,我们称其为键(key),通过key可以快速的查询value

    • 这个对象,我们称其为值(value)

    • 所以字典,也称做键值对(key-value)结构

    • 每个字典中都可以有多个键值对,而每一个键值对我们称其为一项(item)

# 字典
# 使用{}来创建字典
d = {}
'''
创建一个保护有数据的字典
语法:
{key:value,key:value,key:value}
​
1.字典的值可以是任意对象
2.字典的键可以是任意的不可变对象(int str bool tuple ...),但一般都会使用str
3.字典的键不能重复,如果出现重复的,后面的会替换前面的
'''
d ={
    'name': '陈独秀',
    'age': 18,
    'gender': '男',
}
# 通过键来获取值
print(d['name'])

2.字典的使用

  • 创建字典&获取键值&添加key-value&更新字典中的value

'''
​
创建字典①
使用{}
语法:{key:value,key:value,key:value}
​
'''
​
'''
创建字典②
1.使用dict()函数来创建字典
2.每一个参数都是一个键值对,参数名就是键,参数名就是值(这种方式创建的字典,key都是字符串)
'''
d = dict(name='陈独秀', age=18, gender='男')
​
'''
创建字典③
1.可以将一个包含双值子序列的序列转换为字典
2.双值序列,序列中只有两个值 [1,2] ('a',3)
3.子序列,如果序列中的元素也是序列,那么我们就称这个元素为子序列;e.g.  [(1,2),(3,5)]
'''
d = dict([('name', '风'), ('age', 99)])
print(d, type(d))
​
# len()获取字典中键值对的个数
print(len(d))
​
# in 检查字典中是歪包含指定的键
# not in 检查字典中是否不包含指定的键
print('hello' in d)
​
# 获取字典中的值,根据键来获取值
print(d['name'])
​
'''
get(key[,default]) 该方法用来根据键来获取字典中的值
如果获取的值在字典中不存在,会返回None,也可以指定一个默认值,
来作为第二个参数,这样获取不到值时将会返回默认值
'''
print(d.get('name'))
print(d.get('hello', '我是默认值'))
​
# 修改字典
# d[key]=value 如果key存在则覆盖,不存在则添加
d['name'] = 'ke'  # 修改字典的key-value
d['address'] = 'gz'  # 向字典的key-value
print(d)
​
'''
setdefault(key[,default])可以用来向字典中添加key-value
如果key已经存在于字典中,则返回key的值,不会对字典做任何操作
如果key不存在,则向字典中添加key,并设置value
'''
exist_key = d.setdefault('name', 'tester')
not_exist_key = d.setdefault('hello', 'tester')
print(not_exist_key)
​
'''
update([other])
将其他的字典中的key-value添加当前字典中
如果有重复的key,则后边的会替换
'''
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'e': 5, 'f': 6, 'g': 7, 'a': 8}
d1.update(d2)
print(d1)
  • 删除&拷贝

# 删除,可以使用del来删除字典中的key-value
d = {
    'name': '陈独秀',
    'age': 18,
    'gender': '男',
}
​
del d['age']
# popitem()
'''
1.随机删除字典中的一个键值对,一般都会删除最后一个键值对
2.删除之后,它会将删除的key-value作为返回值返回
3.返回的是一个元组,元组中有两个元素,第一个元素是删除的key,第二个元素是删除的value
4.当使用popitem()删除一个空字典时,会抛异常
​
'''
result = d.popitem()
print(result)
​
​
# pop(key[,default])
'''
1.根据key删除字典中的key-value,会将被删除的value返回;
2.如果删除不存在的key,会抛异常
3.如果指定了默认值,再删除不存在的key时,不会报错,而是直接返回默认值
'''
d = {'a': 1, 'b': 2, 'c': 3}
result = d.pop('a')
result = d.pop('a', '这是默认值')
​
# clear()用来清空字典
d.clear()
​
# copy()
'''
1.该方法用于对字典进行浅复制
2.复制以后的对象,和原对象是独立,修改一个不会影响另一个
3.浅复制会简单复制对象内部的值,如果值也是一个可变对象,这个可变对象不会被复制
'''
d = {'a': 1, 'b': 2, 'c': 3}
d2 = d.copy()
​
​
  • 遍历字典

d = {
    'name': '陈独秀',
    'age': 18,
    'gender': '男',
}
​
# keys(),该方法会返回字典的所有的key
for k in d.keys():
    print(k, d[k])
​
# values(),该方法会返回一个序列,序列中保存有字典的值
for v in d.values():
    print(v)
​
# item()
'''
1.该方法会返回字典中所有的项
2.它会返回一个序列,序列中包含有双值序列
3.双值分别是,字典中的key-value
'''
for k, v in d.items():
    print(k, '=', v)

3.集合(set)

  • 集合和列表非常相似

  • 不同点

    • 集合中只能存储不可变对象

    • 集合中存储的对象是无序(不是按照元素的插入顺序保存)

    • 集合中不能出现重复的元素

# 使用{}和来创建集合
s = {10, 3, 5, 1, 2, 1, 1, 1}
​
# 使用set()函数创建集合
# 空集合
s = set()
​
# 可以通过set()来将序列和字典转换为集合
translate_list = set([1, 2, 3, 4, 5])
​
# 使用set()将字典转换为集合时,只会包含字典中的键
translate_dict = set({'a': 1, 'b': 2})
​
# 使用in和not in来检查集合中的元素
print('c' in translate_dict)
​
# 使用len()来获取集合中元素的数量
print(len(s))
​
# add()向集合中添加元素
s.add(25)
​
# update() 将一个集合中的元素添加到当前集合中
# update()可以传递序列或字典作为参数,字典只会使用键
s2 = set('hello')
s.update(s2)
s.update((10, 50, 60))
s.update({'a': 90})
print(s)
​
​
# pop()随机删除并返回一个集合中的元素
s.pop()
​
# remove()删除集合中的指定元素
s.remove(10)
​
# clear()清空集合
s.clear()
​
# copy()对集合进行浅复制
  • 集合的运算

# 创建两个集合
s = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7}
​
# 在对集合做运算时,不会影响原来的集合,而是返回一个运算结果
# & 交集运算,返回两个集合的公共部分
result = s & s2
print('result =', result)
​
# | 并运算,将两个集合合并
result = s | s2
print('result =', result)
​
# - 差集,返回只在s集合中有,s2集合中无的元素
result = s - s2
print('result =', result)
​
# ^ 异或集 获取只在一个集合中出现的元素
result = s ^ s2
print('result =', result)
​
# <= 检查一个集合中是否是另外一个集合的子集
# 如果a集合中的元素全部都在b集合中出现,那么a集合就是b集合的子集,b集合是a集合的超集
​
a = {1, 2, 3}
b = {1, 2, 3, 4, 5}
​
# True
result = a <= b
print('result =', result)
​
# True
result = {1, 2, 3} <= {1, 2, 3}
print('result =', result)
​
# Fault
result = {1, 2, 3, 4, 5} <= {1, 2, 3}
print('result =', result)
​
# <检查一个集合是否是另一个集合的真子集
# 如果超集b中含有子集a中所有的元素,并且b中还有a中没有的元素,则b就是a的真超集,a是b的真子集
​
# Fault
result = {1, 2, 3} < {1, 2, 3}
print('result =', result)
​
# True
result = {1, 2, 3} < {1, 2, 3, 4, 5}
print('result =', result)
​
# >= 检查一个集合是否是另一个的超集
# > 检查一个集合是否是另一个的真超集

七、函数(function)

1.函数介绍

  • 函数也是一个对象

  • 对象是内存中专门用来存储数据的一块区域

  • 函数可以用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次的调用

  • 函数中保存的代码不会立即执行,需要调用函数代码都会执行

# 定义一个函数
'''
函数名必须符合标识符的规范(可以包含字母、数字、下划线、但是不能以数字开头)
def 函数名([形参1,形参2,形参3]):
    函数体
'''
​
def fn():
    print('我是一个函数')
​
# 调用函数
# fn是函数对象,fn()是调用函数
#print是函数对象,print()是调用函数
fn()

2.函数的参数

  • 在定义函数时,可以在函数后的()定义数量不等的形参

  • 形参(形式参数),定义形参就相当于在函数内部声明了变量,但是并不赋值

  • 实参(实际参数)

    • 如果函数定义时,指定了形参,那么在调用函数时也必须传递实参,实参将会赋值给对应的形参,简单来说,有几个形参就得有几个实参

# 定义一个函数,可以用来任意两个数的和
def sum(a, b):
    print(a+b)
# 调用时传实参
sum(1,5)
  • 实参的传递方式

    • 位置参数

      • 将对应位置的实参复制给对应位置的形参

        fn(1, 2, 3)
    • 关键字参数

      • 可以不按照形参定义的顺序去传递,而直接根据参数名去传递参数

        fn(b=1, c=2, a=3)
    • 位置参数和关键字参数可以混合使用,使用时必须将位置参数写到前面

  • 参数的类型

    • 函数在调用时,解析器不会检查实参的类型

    • 实参可以传递任意类型的对象

def fn(a, b):
    print('a =', a)
    print('b =', b)
​
​
fn('我是字符串', 2)
​
​
def fn2(a):
    a[0] = 30
    '''
    在函数中对形参进行重新赋值,不会影响其他的变量
    a = 20
    a是一个列表时,尝试修改列表中的元素
    如果形参执行的是一个对象,当我们通过形参去修改对象时会影响到所有指向该对象的变量
    '''
    print('a= ', a)
​
​
c = [1, 2, 3]
fn2(c)
print('c=', c)
# 如果想不受影响,可以使用copy()或切片的方式,使变量独立
  • 不定长参数

# 在定义函数时,可以在形参前边加一个*,这样这个形参将会获取到所有的实参
# 它将会将所有的实参保存到一个元组中
​
​
# *a会接受所有的位置实参,并且会将这些实参统一保存到一个元组中(装包)
def fn(*a):
    print('a= ', a, type(a))
​
​
fn(1, 2, 3, 4)
​
​
# 定义一个函数,可以求任意个数字的和
​
def sum(*nums):
    result = 0
    # 遍历元组
    for num in nums:
        result += num
    print('求和为:',result)
​
​
sum(55, 88, 99, 88)
​
​
'''
1.带星号的形参只能有一个
2.带星号的参数,可以和其他参数配合使用
3.第一个参数给a,第二个参数给b,剩下的都保存到c的元组
4.可变参数不是必须写在最后,但是注意,带*的参数后的所有参数,必须以关键字参数的形式传递
'''
​
​
def fn2(a, b, *c):
​
    print('a =', a)
    print('b =', b)
    print('c =', c)
​
​
fn2(25, 41, 55, 77, 124, 412, 885)
​
​
def fn3(*a, b, c):
​
    print('a =', a)
    print('b =', b)
    print('c =', c)
​
​
fn3(25, 41, 55, 77, 124, b=412, c=885)
​
​
# 如果在形参的开头直接写一个*,则要求我们的所有的参数必须以关键字参数的形式传递
def fn4(*, a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)
​
​
fn4(a=1, b=2, c=3)
​
# *形参只能接收位置参数,不能接收关键字参数
​
​
# **形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中
# 字典的key就是参数的名字,字典的值就是参数的值
# **形参只能有一个,并且必须写在所有参数的最后
def fn5(**a):
    print('a=', a, type(a))
​
​
fn5(a=1, b='hello', c=True)
​
​
#输出结果
a=  (1, 2, 3, 4) <class 'tuple'>
330
a = 25
b = 41
c = (55, 77, 124, 412, 885)
a = (25, 41, 55, 77, 124)
b = 412
c = 885
a = 1
b = 2
c = 3
a= {'a': 1, 'b': 'hello', 'c': True} <class 'dict'>
​
Process finished with exit code 0
​
​

3.参数的解包

# 参数的解包
def fn4(a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)
​
​
# 创建一个元组
​
t = (10, 20, 30)
​
'''
1.传递实参时,也可以在序列类型的参数前添加星号,这样他会自动将序列中的元素依次作为参数传递
2.这里要求序列中元素的个数必须和形参个数一致
'''
fn4(*t)
​
# 创建一个字典
d = {'a': 100, 'b': 200, 'c': 300}
# 通过 **来对一个字典进行解包操作
​
fn4(**d)

4.返回值

# 返回值是函数执行以后返回的结果
# 可以通过return来指定函数的返回值
# 可以之间使用函数的返回值,也可以通过一个变量来接收函数的返回值
​
​
def sum(*nums):
    result = 0
    # 遍历元组
    for num in nums:
        result += num
    return result
​
​
r = sum(10, 52, 63)
print(r)
​
​
# return后边跟什么值,函数就会返回什么值
# return后边可以跟任意的对象,返回值甚至可以是一个函数
# 如果仅仅写一个return 或者不写 return ,则相当于return None
​
​
# 在函数中,return后的代码都不会执行
​
def fn():
    print('hello')
    return
    print('不会执行')
​
​
​
def fn2():
    for i in range(5):
        # break 用来退出当前循环
        # continue 用来跳过当次循环
        return #用来结束函数
        print(i)
    print('循环执行完毕!')
​
​
fn2()
​
​
def fn3():
    return 10
​
print(fn3) #fn3是函数对象,打印的是函数对象
print(fn3()) #fn3()是调用函数,打印的是返回值

5.文档字符串

# 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是函数的说明
# 当我们编写了文档字符串时,就可以通过help()函数来查看函数的说明
# 文档字符串,直接在函数的第一行写一个字符串就是文档字符串
​
​
def fn(a: int, b: bool, c: str):
    '''
    函数说明信息xxxxxxxxxxxxxx
    :param a: 
    :param b: 
    :param c: 
    :return: 
    '''
    pass

6.作用域(scope)

  • 作用域指的是变量生效的区域

  • 在python中一共有两种作用域(全局/函数)

    • 全局作用域

      • 全局作用域在程序执行时创建,在程序执行结束时销毁

      • 所有函数以外的区域都是全局作用域

      • 在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问

    • 函数作用域

      • 函数作用域在函数调用时创建,在调用结束时销毁

      • 函数每调用一次就会产生一个新的函数作用域

      • 在函数作用域中定义的变量,都是局部变量,它只能在函数内部访问

    • 变量的查找

      • 当使用变量时,会优先在当前作用域中寻找该变量,有则使用

      • 如果当前使用域查找不到,则继续往上一级作用域中查找,有则使用,无则继续查找上一级中查找

      • 直接找到全局作用域,依然没有找到,则会抛出异常:NameError : name 'xxxx' is not defined

# 全局变量
a = 20
​
​
def fn():
    a = 10
    print('函数内部:', 'a=', a)
​
def fn2():
    # 在函数中为变量赋值时,默认都是为局部变量赋值
    # 如果希望在函数内部修改全局变量,则需要使用global关键字来声明变量
    # 声明函数在内部的使用a是全局变量,此时再去修改a时,就是在修改全局的a
    global a
    a = 10
    print('函数内部修改全局变量:', 'a=', a)
​
​
fn()
print('函数外部:', 'a=', a)
​
fn2()

7.命名空间(namespace)

  • 命名空间指的是变量存储的位置,每个变量都需要存储到指定的命名空间当中

  • 每一个作用域都会有一个它对应的命名空间

  • 全局命名空间,用来保存全局变量,函数命名空间用来保存函数中的变量

  • 命名空间实际上就是一个字典,是一个专门用来存储变量的字典

  • locals()用来获取当前作用域的命名空间

  • 如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间,返回的是一个字典

a = 20
# locals()用来获取当前作用域的命名空间
scope = locals()
print(type(scope))
​
def fn():
    # globals()函数可以用来在任意位置获取全局命名空间
    global_scope = globals()

8.递归

  • 递归简单理解就是自己去引用自己

  • 递归式函数,在函数中自己调用自己

  • 无穷递归,如果这个函数被调用,程序的内存会溢出,效果类似于死循环

  • 递归是解决问题的一种方式,它和循环很低,整体思想是将一个大问题分解为一个个小问题,直到问题无法分解时,再去解决问题

  • 递归式函数的两个要件

    • 基线条件

      • 问题可以被分解为最小问题,当满足基线条件时,递归就不在执行

    • 递归条件

      • 将问题继续分解的条件

'''
1! = 1*1
2! = 2*1!
3! = 3*1!
'''
# 求任意数的阶乘
​
​
def factorial(n):
    # 基线条件,判断n是否为1,如果为1则此时不能再继续递归
    if n == 1:
        return 1
​
    # 递归条件
    return n * factorial(n-1)
​
​
print(factorial(10))
​
​
# 判断字符串是不是回文
def hui_wen(s):
    # 如果长度小于2,则字符串一定是回文
    if len(s) < 2:
        return True
    # 如果第一个字符不等于最后一个字符,那么一定不是回文
    elif s[0] != s[-1]:
        return False
    # 递归条件
    return hui_wen(s[1:-1])
​
​
print(hui_wen('abcba'))

9.高阶函数

  • 函数式编程

    • 在Python中,函数是一等对象

    • 一等对象一般都会具有以下特点

      • 对象是在运行时创建的

      • 能赋值给变量或作为数据结构中的元素

      • 能作为参数传递

      • 能作为返回值返回

  • 高阶函数

    • 高阶函数至少要符合以下两个特点中的一个

      • 接收一个或多个函数作为参数

      • 将函数作为返回值返回

# 高阶函数
# 接收函数作为参数,或者将函数作为返回值的函数是高阶函数
# 当我们使用一个函数作为参数时,实际上是将指定的代码传递给目标函数
​
​
def even_number(num):
    if num % 2 != 0:
        return False
    return True
​
​
def uneven_number(num):
    if num % 2 == 0:
        return True
    return False
​
​
def fn(func, lst):
    '''
    fn()函数可以获取列表中偶数或奇数,进行返回
    :return: 返回新列表
    '''
​
    new_list = []
​
    # 对列表进行筛选
    for n in lst:
        if func(n):
            new_list.append(n)
    return new_list
​
​
num = [1, 2, 3, 4, 5, 6, 7, 8]
print(fn(even_number, num))
​
  • 匿名函数

num = [1, 2, 3, 4, 5, 6, 7, 8]
​
​
# filter()
'''
filter()可以从序列中过滤出符合条件的元素,保存到一个新的序列中
参数:
    1.函数,根据该函数来过滤列表(可迭代的结构)
    2.需要过滤的序列(可迭代的结构)
返回值:
    过滤后的新序列(可迭代的结构)
'''
print(list(filter(even_number, num)))
'''
even_number是作为一个参数传递进filter()函数中
而fn4实际上只有一个使用,就是作为filter()的参数
filter()调用完毕之后,even_number就已经没用
'''
​
# 匿名函数 lambda 函数表达式
# lambda函数表达式专门用来创建一些简单的函数,它是函数创建的又一种方式
# 语法: lambda 参数列表 : 返回值
​
r = filter(lambda i:  i % 2 == 0, num)
print(list(r))
​
# map()
# map()函数可以对迭代对象中的所有元素做指定的操作,然后将其添加到一个新的对象中返回
​
l = map(lambda i: i*2, num)
print(list(l))
​
​
# sort()
'''
该方法用来对列表中的元素进行排序
sort()方法默认是直接比较列表中的排序
在sort()可以接收一个关键字参数[key]
key需要一个函数作为参数,当设置了函数作为参数
每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小
'''
str_list = ['a', 'bbb', 'ddddd', 'cc', 'eeeee']
str_list.sort(key=len)
print(str_list)
​
# sorted()
'''
该函数和sort()的用法基本一致,但是sorted()可以对任意对象的序列进行排序
并且使用sorted()排序不会影响原来的对象,而是返回一个新对象
'''
​
l = '124587965426345'
​
print(sorted(l))
  • 闭包(类似java中的private修饰的[私有变量])

    • 将函数作为返回值返回,也是一种高阶函数

    • 这种高阶函数我们也称为闭包,通过闭包可以创建一些只有当前函数能访问的变量

    • 可以将一些私有的数据藏到闭中包

def fn():
    a = 10
​
    # 函数内部再定义一个函数
​
    def inner():
        print('我是fn2', a)
​
    # 将内部函数 inner作为返回值返回
    return inner
​
​
def make_average():
    # 创建一个列表,用来保存数值
    nums = []
​
    # 创建一个函数,用来计算平均值
    def average(n):
        nums.append(n)
        # 求平均值
        return sum(nums) / len(nums)
​
    return average
​
​
get_average = make_average()
​
print(get_average(10))
print(get_average(15))
# 此处nums重新赋值为一个空列表,但不会影响make_average的nums
nums = []
print(get_average(11))
​
  • 装饰器

    • 通过装饰器,可以在不修改原来函数的情况下对函数进行扩展

    • 在开发中,都是通过装饰器来扩展函数功能

    • 在定义函数时,可以通过@装饰器,来使用指定的装饰器,用来装饰当前的函数

    • 可以同时为一个函数指定多个装饰器

import time
​
​
def calculate_time(func):
    # 不定义参数 args元组,kwargs字典
    def wrapper(*args, **kwargs):
        # 扩展部分
        start_time = time.time()
        # 原来的函数部分
        result = func(*args, **kwargs)
        # 扩展部分
        end_time = time.time()
        print(end_time - start_time)
        return result
    # 返回函数本身
    return wrapper
​
​
# 使用add函数时,先调用calculate_time,将add()作为参数进行传递
@calculate_time
def add(a, b):
    time.sleep(1)
    return a + b
​
​
print(add(1, 58))
​
​

八、对象(Object)

1.什么是对象

  • 对象是内存中专门用来存储数据的一块区域

  • 对象中可以存储各种数据(e.g. 数字、布尔值、代码)

  • 对象由三部分组成

    • 对象的标识id

    • 对象的类型type

    • 对象的值value

2.面向对象(oop)

  • python是一门面向对象的编程语言

  • 所谓的面向对象的语言,简单理解就是语言中的所有操作都是通过对象来进行的

  • 面向过程的编程语言

    • 面向过程指将我们的程序逻辑分解为一个一个步骤,通过对每个步骤的抽象,来完成程序

  • 面向对象的编程语言

    • 面向对象的编程语言,关注的是对象,而不关注过程

    • 对于面向对象的语言来说,一切都是对象

    • 面向对象的编程思想,将所有的功能统一保存到对应的对象中

    • 这种方式编写的代码,比较容易阅读,并且比较易于维护,容易复用

3.类(class)

  • 目前所学习的对象都是python内置的对象

  • 内置对象并不能满足所有的需求,在开发中经常需要自定义一些对象

  • 类,简单理解它就是一张图纸,在程序中我们需要根据类创建对象,类就是对象的图纸,也称为对象是类的实例(instance)

  • 如果多个对象是通过一个类创建的,我们称这些对象是一类对象

  • 自定义的类都需要使用大写字母开头,使用驼峰命名法

  • 类也是一个对象

  • 类就是一个用来创建对象的对象

  • 类是type类型的对象,定义类实际上就是定义了一个type类型的对象

# 创建一个int类实例
a = int(10)
# 创建一个str类实例
b = str('hello')
​
​
# 定义一个简单的类
# 使用class关键字来定义类,语法和函数很像
# class 类名([父类]):
#    代码块
# <class '__main__.MyClass'>
class MyClass():
    pass
​
​
#print(MyClass)
​
# 使用MyClass创建一个对象
# 使用类来创建对象,就像调用一个函数一样
​
# mc是通过MyClass创建的对象,mc是MyClass的实例
mc = MyClass()
mc1 = MyClass()
mc2 = MyClass()
​
# mc/mc1/mc2都是MyClass的实例,它们都是一类对象
​
# isinstance()用来检查一个对象是否是一个类的实例
result = isinstance(mc2, MyClass)
result2 = isinstance(mc2, str)
print('result= ', result)
print('result2= ', result2)
​
#运行结果:
result=  True
result2=  False
​
  • 对象的创建流程

    • 创建一个变量mc

    • 在内存中创建一个新对象

    • 将对象的id赋值给变量

class MyClass():
    pass
​
# mc是通过MyClass创建的对象,mc是MyClass的实例
mc = MyClass()
mc1 = MyClass()
mc2 = MyClass()
​
'''
现在我们通过MyClass这个类创建的对象都是一个空对象
也就是对象中实际上什么都没有,就相当于是一个空的盒子
可以向对象中添加变量,对象中的变量称为属性
语法:对象.属性名 = 属性值
'''
mc.name = '陈独秀'
mc1.name = '皮卡丘'
​
print(mc.name)
print(mc1.name)

4.类的定义

  • 类和对象都是对现实生活中的事物或程序中内容的抽象

  • 实际上所有的事物都由两部分构成

    • 数据(属性)

    • 行为(方法)

  • 调用方法,对象.方法名()

  • 方法调用和函数调用的区别

    • 如果是函数调用,则调用时传几个参数,就会有几个实参

    • 若是方法调用,默认传递一个参数,所以方法中至少要定义一个形参

# 定义一个表示人的类
class Person:
    # 在类的代码块中,可以定义变量和函数
    # 在类中所定义的变量,将会成为所有实例的公共属性
    # 所有实例都可以访问这些变量
    name = 'wgf'
​
    # 在类中也可以定义函数,类中定义的函数,我们称为方法
    # 这些方法可以通过该类的所有实例来访问
    def say_hello(self):
        print('hello!')
​
​
# 创建Person的实例
p1 = Person()
p2 = Person()
​
# 调用方法,对象.方法名()
p2.say_hello()
print(p1.name)
​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值