Python:数据类型(二)

2024-05-09 22:58
文章标签 数据类型 python

本文主要是介绍Python:数据类型(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1.基础数据
      • 1.1基本语法
      • 1.2字面量与变量、标识符
      • 1.3 数字
      • 1.4 字符串
      • 1.5 布尔值和空值
      • 1.6 类型检查
    • 2.对象
      • 2.1 理论介绍
      • 2.2 类型转换
      • 2.3 可变对象
      • 2.4 == 与 is
      • 2.5 类
      • 2.6 对象初始化
      • 2.7 封装
      • 2.8 继承
      • 2.9 多重继承
      • 2.10 多态
      • 2.11 属性和方法
      • 2.12 垃圾回收
      • 2.13 特殊方法
      • 2.14 模块
      • 2.15 包
      • 2.16 标准库
    • 3.序列
      • 3.1 列表
      • 3.2 切片
      • 3.3 通用操作
      • 3.4 修改元素
      • 3.5 列表方法
      • 3.6 遍历列表
    • 4.元组
    • 5.字典(dict)
      • 5.1 使用
      • 5.2 遍历
    • 6. 集合(set)

1.基础数据

1.1基本语法

1.在Python中严格区分大小写
2.Python中的每一行就是一条语句,每条语句以换行结束
3.Python中每一行语句不要过长(规范中建议每行不要超过80个字符)
4.一条语句可以分多行编写,多行编写时语句后边以\结尾
5.Python是缩进严格的语言,所以在Python中不要随便写缩进
6.在Python中使用#来表示注释,#后的内容都属于注释,注释的内容将会被解释器所忽略,我们可以通过注释来对程序进行解释说明,一定要养成良好的编写注释的习惯
8注释要求简单明了,一般习惯上#后边会跟着一个空格

1.2字面量与变量、标识符

字面量:比如1,2,3,A,b这些,根据字面意思,可以在程序中一个一个使用

变量:用来保存字面量,比如a = 10 ,a 这个就是变量
1.python中的变量不需要进行声明就可以使用,直接为变量赋值即可,但是若变量没有经过赋值,就直接使用,则会报错,比如print(a) ,a没有被赋值,就会报错
2.Python是一个动态类型的语言,可以为变量赋任意类型的值,也可以任意改变量的值,比如 a = 10后,可以又赋值a = “sss”

标识符
在Python中所有可以自主命名的内容都属于标识符
比如:变量名、函数名、类名
标识符必须遵循标识符的规范
1.标识符中可以含有字母、数字、_,但是不能使用数字开头
例子:a 1 al 1a
2.标识符不能是Python中的关键字和保留字
也不建议使用Python中的函数名作为标识符,因为这样会导致函数被覆盖
3.命名规范:
在Python中注意遵循两种命名规范:
下划线命名法
所有字母小写,单词之间使用分割
max_length min_length hello_world xxx_yyy_zzz
帕斯卡命名法(大驼峰命名法)
首字母大写,每个单词开头字母大写,其余字母小写
MqxLength Mintength Helloworld XxxYyyzzz
如果使用不符合标准的标识符,将会报错 SyntaxError:invalid syntax

1.3 数字

#在Python数值分成了三种:整数、浮点数(小数)、复数
#在Python中所有的整数都是int类型
a-10
b=20
#Python中的整数的大小没有限制,可以是一个无限大的整数
#C=999999999999999999999999999999999999999999999**100
#如果数字的长度过大,可以使用下划线作为分隔符
c=123_456_789
I
#d=0123
10进制的数字不能以0开头
#其他进制的整数,只要是数字打印时一定是以十进制的形式显示的
#二进制0b开头
c=Ob10 #二进制的10
#八进制0o开头
C=0o18
#十六进制0x开头
C=0x10
#也可以通过运算符来对数字进行运算,并且可以保证整数运算的精确
c=-100
C= C+1
#浮点数(小数),在Python中所有的小数都是float类型
c=1.23
C=4.56
#对浮点数进行运算,可能会得到一个不精确的值,比如
0.1+0.2   
# 0.30000000000000004  就好比10进制里不能完全得到三分之一的结果一样,只能得一个近似值,所以涉及金额方面的
#一定不能用浮点计算

1.4 字符串

1.字符串

# 字符串(str)
# 字符串用来表示一段文本信息,字符串是程序中使用的最多的数据类型
# 在Python中字符串需要使用引号引起来s = 'hello'
# s = abc # 字符串必须使用引号引起来,不使用不是字符串
# 引号可以是双引号,也可以是单引号,但是注意不要混着用
s = 'hello'
s = "hello"
# s = 'hello" 引号不能混合使用  SyntaxError: EOL while scanning string literal# 相同的引号之间不能嵌套
# s = "子曰:"学而时习之,乐呵乐呵!""
s = '子曰:"学而时习之,乐呵乐呵!"'# 长字符串
# 单引号和双引号不能跨行使用
s = '锄禾日当午,\
汗滴禾下土,\
谁知盘中餐,\
粒粒皆辛苦'# 使用三重引号来表示一个长字符串 ''' """
# 三重引号可以换行,并且会保留字符串中的格式s = '''锄禾日当午,
汗滴禾下土,
谁知盘中餐,
粒粒皆辛苦'''# 转义字符
# 可以使用 \ 作为转义字符,通过转义字符,可以在字符串中使用一些特殊的内容
# 例子:
#   \' 表示'
#   \" 表示"
#   \t 表示制表符
#   \n 表示换行符
#   \\ 表示反斜杠
#   \uxxxx 表示Unicode编码
s = "子曰:\"学而时习之,\\\\n乐呵乐呵!\""s = '\u2250'
print(s)

2.字符串格式化

# 格式化字符串
a = 'hello'# 字符串之间也可以进行加法运算
# 如果将两个字符串进行相加,则会自动将两个字符串拼接为一个
a = 'abc' + 'haha' + '哈哈'
# a = 123 
# 字符串不能和其他的类型进行加法运算,如果做了会出现异常 TypeError: must be str, not int
# print("a = "+a) # 这种写法在Python中不常见
a = 123
# print('a =',a)# 在创建字符串时,可以在字符串中指定占位符
# %s 在字符串中表示任意字符
# %f 浮点数占位符
# %d 整数占位符
b = 'Hello %s'%'孙悟空'
b = 'hello %s 你好 %s'%('tom','孙悟空') #hello tom 你好 孙悟空
b = 'hello %3.5s'%'abcdefg' # %3.5s字符串的长度限制在3-5之间
b = 'hello %s'%123.456
b = 'hello %.2f'%123.456
b = 'hello %d'%123.95
b = '呵呵'# print('a = %s'%a)# 格式化字符串,可以通过在字符串前添加一个f来创建一个格式化字符串
# 在格式化字符串中可以直接嵌入变量
c = f'hello {a} {b}'print(f'a = {a}')# 练习 创建一个变量保存你的名字,然后通过四种格式化字符串的方式
#   在命令行中显示,欢迎 xxx 光临!# 创建一个变量来保存你的名字
name = '孙悟空'# 使用四种方式来输出,欢迎 xxx 光临
# 拼串
print('欢迎 '+name+' 光临!')
# 多个参数
print('欢迎',name,'光临!')
# 占位符
print('欢迎 %s 光临!'%name)
# 格式化字符串
print(f'欢迎 {name} 光临!')# 字符串的复制(将字符串和数字相乘)
a = 'abc'
# * 在语言中表示乘法
# 如果将字符串和数字相乘,则解释器会将字符串重复指定的次数并返回
a = a * 20print(a)

1.5 布尔值和空值

# 布尔值(bool)
# 布尔值主要用来做逻辑判断
# 布尔值一共有两个 True 和 False
# True表示真 False表示假
a = True
a = False
# print('a =',a)# 布尔值实际上也属于整型,True就相当于1,False就相当于0
# print(1 + False)# None(空值)
# None专门用来表示不存在
b = None
print(b)

1.6 类型检查

# 通过类型检查,可以检查只能值(变量)的类型a = 123 # 数值
b = '123' # 字符串# print('a =',a)
# print('b =',b)、# type()用来检查值的类型
# 该函数会将检查的结果作为返回值返回,可以通过变量来接收函数的返回值
c = type('123')
c = type(a)
# print(type(b))
print(type(1)) # <class 'int'>
print(type(1.5)) # <class 'float'>
print(type(True)) # <class 'bool'>
print(type('hello'))  # <class 'str'>
print(type(None)) # <class 'NoneType'>

2.对象

2.1 理论介绍

- Python是一门面向对象的语言
- 一切皆对象!
- 程序运行当中,所有的数据都是存储到内存当中然后再运行的!
- 对象就是内存中专门用来存储指定数据的一块区域
- 对象实际上就是一个容器,专门用来存储数据
- 像我们之前学习的数值、字符串、布尔值、None都是对象
- 每个对象中都要保存三种数据- id(标识)> id用来标识对象的唯一性,每一个对象都有唯一的id> 对象的id就相当于人的身份证号一样> 可以通过id()函数来查看对象的id> id是由解析器生成的,在CPython中,id就是对象的内存地址> 对象一旦创建,则它的id永远不能再改变- type(类型)> 类型用来标识当前对象所属的类型> 比如:int str float bool 。。。> 类型决定了对象有哪些功能> 通过type()函数来查看对象的类型> Python是一门强类型的语言,对象一旦创建类型便不能修改- value(值)> 值就是对象中存储的具体的数据> 对于有些对象值是可以改变的> 对象分成两大类,可变对象 不可变对象可变对象的值可以改变不可变对象的值不能改变,之前学习的对象都是不可变对象

变量和对象

- 对象并没有直接存储到变量中,在Python中变量更像是给对象起了一个别名
- 变量中存储的不是对象的值,而是对象的id(内存地址),当我们使用变量时,实际上就是在通过对象id在查找对象
- 变量中保存的对象,只有在为变量重新赋值时才会改变
- 变量和变量之间是相互独立的,修改一个变量不会影响另一个变量

2.2 类型转换

在这里插入图片描述

# 类型转换四个函数 int() float() str() bool()
# int() 可以用来将其他的对象转换为整型
# 规则:
#   布尔值:True -> 1   False -> 0
#   浮点数:直接取整,省略小数点后的内容
#   字符串:合法的整数字符串,直接转换为对应的数字
#           如果不是一个合法的整数字符串,则报错 ValueError: invalid literal for int() with base 10: '11.5'
#   对于其他不可转换为整型的对象,直接抛出异常 ValueError
# float() 和 int()基本一致,不同的是它会将对象转换为浮点数
# str() 可以将对象转换为字符串
#  True -> 'True'
#  False -> 'False'
#  123 -> '123' 
#  。。。
#  bool() 可以将对象转换为布尔值,任何对象都可以转换为布尔值
#   规则:对于所有表示空性的对象都会转换为False,其余的转换为True
#       哪些表示的空性:0 、 None 、 '' 。。。a = True# 调用int()来将a转换为整型
# int()函数不会对原来的变量产生影响,他是对象转换为指定的类型并将其作为返回值返回
# 如果希望修改原来的变量,则需要对变量进行重新赋值
a = int(a)a = False
a = int(a)a = '123'
a = int(a)a = 11.6
a = int(a)a = '11.5'
# a = int(a)a = None
# a = int(a)a = 1
a = float(a)a = False
a = float(a)a = 123
a = str(a)a = None
a = bool(a)print('a =',a)
print('a的类型是',type(a))
# b = 456
# print('hello'+str(b))

2.3 可变对象

可变对象,就是改变对象里面的值value

- 每个对象中都保存了三个数据:id(标识)type(类型)value(值)    - 列表就是一个可变对象a = [1,2,3]- a[0] = 10 (改对象)- 这个操作是在通过变量去修改对象的值- 这种操作不会改变变量所指向的对象    - 当我们去修改对象时,如果有其他变量也指向了该对象,则修改也会在其他的变量中体现- a = [4,5,6] (改变量)- 这个操作是在给变量重新赋值- 这种操作会改变变量所指向的对象- 为一个变量重新赋值时,不会影响其他的变量- 一般只有在为变量赋值时才是修改变量,其余的都是修改对象
# # 可变对象
# a = [1,2,3]
# print('修改前:', a , id(a))# # 通过索引修改列表
# a[0] = 10
# print('修改后:', a , id(a))# # 为变量重新赋值
# a = [4,5,6]
# print('修改后:', a , id(a))a = [1,2,3]
b = a
# b[0] = 10
b = [10,2,3]
# print("a",a,id(a))
# print("b",b,id(b))

2.4 == 与 is

# == !=  is is not
# == != 比较的是对象的值是否相等 
# is is not 比较的是对象的id是否相等(比较两个对象是否是同一个对象)a = [1,2,3]
b = [1,2,3]
print(a,b)
print(id(a),id(b))
print(a == b) # a和b的值相等,使用==会返回True
print(a is b) # a和b不是同一个对象,内存地址不同,使用is会返回False

2.5 类

- 我们目前所学习的对象都是Python内置的对象
- 但是内置对象并不能满足所有的需求,所以我们在开发中经常需要自定义一些对象
- 类,简单理解它就相当于一个图纸。在程序中我们需要根据类来创建对象
- 类就是对象的图纸!
- 我们也称对象是类的实例(instance)
- 如果多个对象是通过一个类创建的,我们称这些对象是一类对象
-int() float() bool() str() list() dict() .... 这些都是类
- a = int(10) # 创建一个int类的实例 等价于 a = 10
- 我们自定义的类都需要使用大写字母开头,使用大驼峰命名法(帕斯卡命名法)来对类命名- 类也是一个对象!
- 类就是一个用来创建对象的对象!
- 类是type类型的对象,定义类实际上就是定义了一个type类型的对象
a = int(10) # 创建一个int类的实例
b = str('hello') # 创建一个str类的实例# print(a , type(a))
# print(b , type(b))# 定义一个简单的类
# 使用class关键字来定义类,语法和函数很像!
# class 类名([父类]):
#   代码块
# <class '__main__.MyClass'>
class MyClass():pass# print(MyClass)
# 使用MyClass创建一个对象
# 使用类来创建对象,就像调用一个函数一样
mc = MyClass() # mc就是通过MyClass创建的对象,mc是MyClass的实例
mc_2 = MyClass()
mc_3 = MyClass()
mc_4 = MyClass()
# mc mc_2 mc_3 mc_4 都是MyClass的实例,他们都是一类对象
# isinstance()用来检查一个对象是否是一个类的实例
result = isinstance(mc_2,MyClass)
result = isinstance(mc_2,str)# print(mc , type(mc))
# print('result =',result)# print(id(MyClass) , type(MyClass))# 现在我们通过MyClass这个类创建的对象都是一个空对象
# 也就是对象中实际上什么都没有,就相当于是一个空的盒子
# 可以向对象中添加变量,对象中的变量称为属性
# 语法:对象.属性名 = 属性值
mc.name = '孙悟空'
mc_2.name = '猪八戒'print(mc_2.name)

2.6 对象初始化

#创建一个对象流程
p1 = Person()的运行流程1.创建一个变量2.在内存中创建一个新对象3.__init__(self)方法执行4.将对象的id赋值给变量#类的基本结构
class 类名([父类]) :公共的属性... # 对象的初始化方法def __init__(self,...):...# 其他的方法    def method_1(self,...):...def method_2(self,...):...... 
- 类和对象都是对现实生活中的事物或程序中的内容的抽象
- 实际上所有的事物都由两部分构成:1.数据(属性)2.行为(方法)- 在类的代码块中,我们可以定义变量和函数,变量会成为该类实例的公共属性,所有的该类实例都可以通过 对象.属性名 的形式访问 函数会成为该类实例的公共方法,所有该类实例都可以通过 对象.方法名() 的形式调用方法- 注意:方法调用时,第一个参数由解析器自动传递,所以定义方法时,至少要定义一个形参! - 实例为什么能访问到类中的属性和方法类中定义的属性和方法都是公共的,任何该类实例都可以访问- 属性和方法查找的流程当我们调用一个对象的属性时,解析器会先在当前对象中寻找是否含有该属性,如果有,则直接返回当前的对象的属性值,如果没有,则去当前对象的类对象中去寻找,如果有则返回类对象的属性值,如果类对象中依然没有,则报错!- 类对象和实例对象中都可以保存属性(方法)- 如果这个属性(方法)是所有的实例共享的,则应该将其保存到类对象中- 如果这个属性(方法)是某个实例独有,则应该保存到实例对象中     - 一般情况下,属性保存到实例对象中而方法需要保存到类对象中    

在这里插入图片描述

class Person :# 在类中可以定义一些特殊方法(魔术方法)# 特殊方法都是以__开头,__结尾的方法# 特殊方法不需要我们自己调用,不要尝试去调用特殊方法# 特殊方法将会在特殊的时刻自动调用# 学习特殊方法:#   1.特殊方法什么时候调用#   2.特殊方法有什么作用# 创建对象的流程# p1 = Person()的运行流程#   1.创建一个变量#   2.在内存中创建一个新对象#   3.__init__(self)方法执行#   4.将对象的id赋值给变量# init会在对象创建以后离开执行# init可以用来向新创建的对象中初始化属性# 调用类创建对象时,类后边的所有参数都会依次传递到init()中# self不是关键字,是约定写的,可以叫a,b也行,因为方法的第一个参数,默认就是调用方法的对象本身def __init__(self,name):# print(self)# 通过self向新建的对象中初始化属性self.name = namedef say_hello(self):print('大家好,我是%s'%self.name)# 目前来讲,对于Person类来说name是必须的,并且每一个对象中的name属性基本上都是不同
# 而我们现在是将name属性在定义为对象以后,手动添加到对象中,这种方式很容易出现错误
# 我们希望,在创建对象时,必须设置name属性,如果不设置对象将无法创建
#   并且属性的创建应该是自动完成的,而不是在创建对象以后手动完成
# p1 = Person()
# # 手动向对象添加name属性
# p1.name = '孙悟空'# p2 = Person()
# p2.name = '猪八戒'# p3 = Person()
# p3.name = '沙和尚'# p3.say_hello()p1 = Person('孙悟空')
p2 = Person('猪八戒')
p3 = Person('沙和尚')
p4 = Person('唐僧')
# p1.__init__() 不要这么做# print(p1.name)
# print(p2.name)
# print(p3.name)
# print(p4.name)p4.say_hello()

2.7 封装

# 封装是面向对象的三大特性之一
# 封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法
# 如何隐藏一个对象中的属性?
#   - 将对象的属性名,修改为一个外部不知道的名字
# 如何获取(修改)对象中的属性?
#   - 需要提供一个getter和setter方法使外部可以访问到属性
#   - getter 获取对象中的指定属性(get_属性名)
#   - setter 用来设置对象的指定属性(set_属性名)
# 使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全性
#   1.隐藏了属性名,使调用者无法随意的修改对象中的属性
#   2.增加了getter和setter方法,很好的控制的属性是否是只读的
#       如果希望属性是只读的,则可以直接去掉setter方法
#       如果希望属性不能被外部访问,则可以直接去掉getter方法
#   3.使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的
#   4.使用getter方法获取属性,使用setter方法设置属性
#       可以在读取属性和修改属性的同时做一些其他的处理
#   5.使用getter方法可以表示一些计算的属性class Dog:'''表示狗的类'''def __init__(self , name , age):#这里用hidden_name来保存内部值,外面不知道这个属性self.hidden_name = nameself.hidden_age = agedef say_hello(self):print('大家好,我是 %s'%self.hidden_name) def get_name(self):'''get_name()用来获取对象的name属性'''    # print('用户读取了属性')return self.hidden_namedef set_name(self , name):# print('用户修改了属性')self.hidden_name = namedef get_age(self):return self.hidden_agedef set_age(self , age):if age > 0 :self.hidden_age = age    d = Dog('旺财',8)# d.say_hello()# 调用setter来修改name属性 
d.set_name('小黑')
d.set_age(-10)# d.say_hello()
print(d.get_age())

隐藏类中的属性,用_开头,这样外部就不能访问了,其实_打头的,python会自动给它另起名

class Rectangle:'''表示矩形的类'''def __init__(self,width,height):self.hidden_width = widthself.hidden_height = heightdef get_width(self):return self.hidden_widthdef get_height(self):return self.hidden_height   def set_width(self , width):self.hidden_width = width def set_height(self , height):self.hidden_height = height def get_area(self):return self.hidden_width * self.hidden_height        # r = Rectangle(5,2)  
# r.set_width(10)
# r.set_height(20)# print(r.get_area())     # 可以为对象的属性使用双下划线开头,__xxx
# 双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问
# 其实隐藏属性只不过是Python自动为属性改了一个名字
#   实际上是将名字修改为了,_类名__属性名 比如 __name -> _Person__name
# class Person:
#     def __init__(self,name):
#         self.__name = name#     def get_name(self):
#         return self.__name#     def set_name(self , name):
#         self.__name = name        # p = Person('孙悟空')# print(p.__name) __开头的属性是隐藏属性,无法通过对象访问
# p.__name = '猪八戒'
# print(p._Person__name)
# p._Person__name = '猪八戒'# print(p.get_name())# 使用__开头的属性,实际上依然可以在外部访问,所以这种方式我们一般不用
#   一般我们会将一些私有属性(不希望被外部访问的属性)以_开头
#   一般情况下,使用_开头的属性都是私有属性,没有特殊需要不要修改私有属性
class Person:def __init__(self,name):self._name = namedef get_name(self):return self._namedef set_name(self , name):self._name = name   p = Person('孙悟空')print(p._name)

property装饰类,根据注解来设置

class Person:def __init__(self,name,age):self._name = nameself._age = age# property装饰器,用来将一个get方法,转换为对象的属性# 添加为property装饰器以后,我们就可以像调用属性一样使用get方法# 使用property装饰的方法,必须和属性名是一样的@property    def name(self):print('get方法执行了~~~')return self._name# setter方法的装饰器:@属性名.setter@name.setter    def name(self , name):print('setter方法调用了')self._name = name        @propertydef age(self):return self._age@age.setter    def age(self , age):self._age = age   p = Person('猪八戒',18)p.name = '孙悟空'
p.age = 28print(p.name,p.age)

2.8 继承

# 继承# 定义一个类 Animal(动物)
#   这个类中需要两个方法:run() sleep() 
class Animal:def run(self):print('动物会跑~~~')def sleep(self):print('动物睡觉~~~')# def bark(self):#     print('动物嚎叫~~~')   # 定义一个类 Dog(狗)
#   这个类中需要三个方法:run() sleep() bark()
# class Dog:
#     def run(self):
#         print('狗会跑~~~')#     def sleep(self):
#         print('狗睡觉~~~')#     def bark(self):
#         print('汪汪汪~~~') # 有一个类,能够实现我们需要的大部分功能,但是不能实现全部功能
# 如何能让这个类来实现全部的功能呢?
#   ① 直接修改这个类,在这个类中添加我们需要的功能
#       - 修改起来会比较麻烦,并且会违反OCP原则
#   ② 直接创建一个新的类
#       - 创建一个新的类比较麻烦,并且需要大量的进行复制粘贴,会出现大量的重复性代码
#   ③ 直接从Animal类中来继承它的属性和方法
#       - 继承是面向对象三大特性之一
#       - 通过继承我们可以使一个类获取到其他类中的属性和方法
#       - 在定义类时,可以在类名后的括号中指定当前类的父类(超类、基类、super)
#           子类(衍生类)可以直接继承父类中的所有的属性和方法
#           
#  通过继承可以直接让子类获取到父类的方法或属性,避免编写重复性的代码,并且也符合OCP原则
#   所以我们经常需要通过继承来对一个类进行扩展class Dog(Animal):def bark(self):print('汪汪汪~~~') def run(self):print('狗跑~~~~')    class Hashiqi(Dog):def fan_sha(self):print('我是一只傻傻的哈士奇')        d = Dog()
h = Hashiqi()# d.run()
# d.sleep()
# d.bark()# r = isinstance(d , Dog)
# r = isinstance(d , Animal)
# print(r)# 在创建类时,如果省略了父类,则默认父类为object
#   object是所有类的父类,所有类都继承自object
class Person(object):pass# issubclass() 检查一个类是否是另一个类的子类
# print(issubclass(Animal , Dog))
# print(issubclass(Animal , object))
# print(issubclass(Person , object))# isinstance()用来检查一个对象是否是一个类的实例
#   如果这个类是这个对象的父类,也会返回True
#   所有的对象都是object的实例
print(isinstance(print , object))

方法重写

# 继承# 定义一个类 Animal(动物)
#   这个类中需要两个方法:run() sleep() 
class Animal:def run(self):print('动物会跑~~~')def sleep(self):print('动物睡觉~~~')class Dog(Animal):def bark(self):print('汪汪汪~~~') def run(self):print('狗跑~~~~')    # 如果在子类中如果有和父类同名的方法,则通过子类实例去调用方法时,
#   会调用子类的方法而不是父类的方法,这个特点我们成为叫做方法的重写(覆盖,override)
# 创建Dog类的实例
# d = Dog()# d.run()# 当我们调用一个对象的方法时,
#   会优先去当前对象中寻找是否具有该方法,如果有则直接调用
#   如果没有,则去当前对象的父类中寻找,如果父类中有则直接调用父类中的方法,
#   如果没有,则去父类的父类中寻找,以此类推,直到找到object,如果依然没有找到,则报错
class A(object):def test(self):print('AAA')class B(A):def test(self):print('BBB')class C(B):def test(self):print('CCC')   # 创建一个c的实例
c = C()
c.test()

super,通过这个来直接访问父类

class Animal:def __init__(self,name):self._name = namedef run(self):print('动物会跑~~~')def sleep(self):print('动物睡觉~~~')@propertydef name(self):return self._name@name.setter    def name(self,name):self._name = name# 父类中的所有方法都会被子类继承,包括特殊方法,也可以重写特殊方法
class Dog(Animal):def __init__(self,name,age):# 希望可以直接调用父类的__init__来初始化父类中定义的属性# super() 可以用来获取当前类的父类,#   并且通过super()返回对象调用父类方法时,不需要传递selfsuper().__init__(name)self._age = agedef bark(self):print('汪汪汪~~~') def run(self):print('狗跑~~~~')   @propertydef age(self):return self._age@age.setter    def age(self,age):self._age = name        d = Dog('旺财',18) print(d.name)       
print(d.age)  

2.9 多重继承

class A(object):def test(self):print('AAA')class B(object):def test(self):print('B中的test()方法~~')def test2(self):print('BBB') # 在Python中是支持多重继承的,也就是我们可以为一个类同时指定多个父类
#   可以在类名的()后边添加多个类,来实现多重继承
#   多重继承,会使子类同时拥有多个父类,并且会获取到所有父类中的方法
# 在开发中没有特殊的情况,应该尽量避免使用多重继承,因为多重继承会让我们的代码过于复杂
# 如果多个父类中有同名的方法,则会现在第一个父类中寻找,然后找第二个,然后找第三个。。。
#   前边父类的方法会覆盖后边父类的方法
class C(A,B):pass# 类名.__bases__ 这个属性可以用来获取当前类的所有父类    
# print(C.__bases__) (<class '__main__.B'>,)
# print(B.__bases__) (<class 'object'>,)# print(C.__bases__) # (<class '__main__.A'>, <class '__main__.B'>)c = C()c.test()

2.10 多态

# 多态是面向对象的三大特征之一
# 多态从字面上理解是多种形态
# 狗(狼狗、藏獒、哈士奇、古牧 。。。)
# 一个对象可以以不同的形态去呈现# 定义两个类
class A:def __init__(self,name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self,name):self._name = name   class B:def __init__(self,name):self._name = namedef __len__(self):return 10@propertydef name(self):return self._name@name.setterdef name(self,name):self._name = name   class C:passa = A('孙悟空')
b = B('猪八戒')
c = C()# 定义一个函数
# 对于say_hello()这个函数来说,只要对象中含有name属性,它就可以作为参数传递
#   这个函数并不会考虑对象的类型,只要有name属性即可
# obj就可以接收任何实例,只要这个实例里有name方法,obj就可以接收使用,就可以当多态来用
def say_hello(obj):print('你好 %s'%obj.name)# 在say_hello_2中我们做了一个类型检查,也就是只有obj是A类型的对象时,才可以正常使用,
#   其他类型的对象都无法使用该函数,这个函数就违反了多态
# 违反了多态的函数,只适用于一种类型的对象,无法处理其他类型对象,这样导致函数的适应性非常的差
# 注意,向isinstance()这种函数,在开发中一般是不会使用的!
def say_hello_2(obj):# 做类型检查if isinstance(obj , A):print('你好 %s'%obj.name)    
# say_hello(b)    
# say_hello_2(b)# 鸭子类型
# 如果一个东西,走路像鸭子,叫声像鸭子,那么它就是鸭子# len()
# 之所以一个对象能通过len()来获取长度,是因为对象中具有一个特殊方法__len__
# 换句话说,只要对象中具有__len__特殊方法,就可以通过len()来获取它的长度
l = [1,2,3]
s = 'hello'# print(len(l))
# print(len(s))
print(len(b))
print(len(c))# 面向对象的三大特征:
#   封装
#       - 确保对象中的数据安全
#   继承
#       - 保证了对象的可扩展性
#   多态
#       - 保证了程序的灵活性

2.11 属性和方法

# 定义一个类
class A(object):# 类属性# 实例属性# 类方法# 实例方法# 静态方法# 类属性,直接在类中定义的属性是类属性#   类属性可以通过类或类的实例访问到#   但是类属性只能通过类对象来修改,无法通过实例对象修改count = 0def __init__(self):# 实例属性,通过实例对象添加的属性属于实例属性#   实例属性只能通过实例对象来访问和修改,类对象无法访问修改self.name = '孙悟空'# 实例方法#   在类中定义,以self为第一个参数的方法都是实例方法#   实例方法在调用时,Python会将调用对象作为self传入  #   实例方法可以通过实例和类去调用#       当通过实例调用时,会自动将当前调用对象作为self传入#       当通过类调用时,不会自动传递self,此时我们必须手动传递selfdef test(self):print('这是test方法~~~ ' , self)    # 类方法    # 在类内部使用 @classmethod 来修饰的方法属于类方法# 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象#   类方法和实例方法的区别,实例方法的第一个参数是self,而类方法的第一个参数是cls#   类方法可以通过类去调用,也可以通过实例调用,没有区别@classmethoddef test_2(cls):print('这是test_2方法,他是一个类方法~~~ ',cls)print(cls.count)# 静态方法# 在类中使用 @staticmethod 来修饰的方法属于静态方法  # 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用  # 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数# 静态方法一般都是一些工具方法,和当前类无关@staticmethoddef test_3():print('test_3执行了~~~')a = A()
# 实例属性,通过实例对象添加的属性属于实例属性
# a.count = 10
# A.count = 100
# print('A ,',A.count) 
# print('a ,',a.count) 
# print('A ,',A.name) 
# print('a ,',a.name)   # a.test() 等价于 A.test(a)# A.test_2() 等价于 a.test_2()A.test_3()
a.test_3()

在这里插入图片描述

2.12 垃圾回收

# 就像我们生活中会产生垃圾一样,程序在运行过程当中也会产生垃圾
# 程序运行过程中产生的垃圾会影响到程序的运行的运行性能,所以这些垃圾必须被及时清理
# 没用的东西就是垃圾
# 在程序中没有被引用的对象就是垃圾,这种垃圾对象过多以后会影响到程序的运行的性能
#   所以我们必须进行及时的垃圾回收,所谓的垃圾回收就是讲垃圾对象从内存中删除
# 在Python中有自动的垃圾回收机制,它会自动将这些没有被引用的对象删除,
#   所以我们不用手动处理垃圾回收class A:def __init__(self):self.name = 'A类'# del是一个特殊方法,它会在对象被垃圾回收前调用def __del__(self):print('A()对象被删除了~~~',self)a = A()
b = a # 又使用一个变量b,来引用a对应的对象print(a.name)# a = None # 将a设置为了None,此时没有任何的变量对A()对象进行引用,它就是变成了垃圾
# b = None
# del a
# del b
input('回车键退出...')

2.13 特殊方法

# 特殊方法,也称为魔术方法
# 特殊方法都是使用__开头和结尾的
# 特殊方法一般不需要我们手动调用,需要在一些特殊情况下自动执行# 定义一个Person类
class Person(object):"""人类"""def __init__(self, name , age):self.name = nameself.age = age# __str__()这个特殊方法会在尝试将对象转换为字符串的时候调用# 它的作用可以用来指定对象转换为字符串的结果  (print函数)  def __str__(self):return 'Person [name=%s , age=%d]'%(self.name,self.age)        # __repr__()这个特殊方法会在对当前对象使用repr()函数时调用# 它的作用是指定对象在 ‘交互模式’中直接输出的效果    def __repr__(self):return 'Hello'        # object.__add__(self, other)# object.__sub__(self, other)# object.__mul__(self, other)# object.__matmul__(self, other)# object.__truediv__(self, other)# object.__floordiv__(self, other)# object.__mod__(self, other)# object.__divmod__(self, other)# object.__pow__(self, other[, modulo])# object.__lshift__(self, other)# object.__rshift__(self, other)# object.__and__(self, other)# object.__xor__(self, other)# object.__or__(self, other)# object.__lt__(self, other) 小于 <# object.__le__(self, other) 小于等于 <=# object.__eq__(self, other) 等于 ==# object.__ne__(self, other) 不等于 !=# object.__gt__(self, other) 大于 ># object.__ge__(self, other) 大于等于 >= # __len__()获取对象的长度# object.__bool__(self)# 可以通过bool来指定对象转换为布尔值的情况def __bool__(self):return self.age > 17# __gt__会在对象做大于比较的时候调用,该方法的返回值将会作为比较的结果# 他需要两个参数,一个self表示当前对象,other表示和当前对象比较的对象# self > otherdef __gt__(self , other):return self.age > other.age# 创建两个Person类的实例        
p1 = Person('孙悟空',18)
p2 = Person('猪八戒',28)# 打印p1
# 当我们打印一个对象时,实际上打印的是对象的中特殊方法 __str__()的返回值
# print(p1) # <__main__.Person object at 0x04E95090>
# print(p1)
# print(p2)# print(repr(p1))# t = 1,2,3
# print(t) # (1, 2, 3)# print(p1 > p2)
# print(p2 > p1)# print(bool(p1))# if p1 :
#     print(p1.name,'已经成年了')
# else :
#     print(p1.name,'还未成年了')

2.14 模块

# 模块(module)
# 模块化,模块化指将一个完整的程序分解为一个一个小的模块
#   通过将模块组合,来搭建出一个完整的程序
# 不采用模块化,统一将所有的代码编写到一个文件中
# 采用模块化,将程序分别编写到多个文件中
#   模块化的有点:
#       ① 方便开发
#       ② 方便维护
#       ③ 模块可以复用!# 在Python中一个py文件就是一个模块,要想创建模块,实际上就是创建一个python文件
# 注意:模块名要符号标识符的规范# 在一个模块中引入外部模块
# ① import 模块名 (模块名,就是python文件的名字,注意不要py)
# ② import 模块名 as 模块别名
#   - 可以引入同一个模块多次,但是模块的实例只会创建一个
#   - import可以在程序的任意位置调用,但是一般情况下,import语句都会统一写在程序的开头
#   - 在每一个模块内部都有一个__name__属性,通过这个属性可以获取到模块的名字
#   - __name__属性值为 __main__的模块是主模块,一个程序中只会有一个主模块
#       主模块就是我们直接通过 python 执行的模块
import test_module as test# print(test.__name__)
print(__name__)

引入部分

# import m# # 访问模块中的变量:模块名.变量名
# # print(m.a , m.b)# # m.test2()# p = m.Person()# print(p.name)def test2():print('这是主模块中的test2')# 也可以只引入模块中的部分内容
# 语法 from 模块名 import 变量,变量....
# from m import Person
# from m import test
# from m import Person,test
# from m import * # 引入到模块中所有内容,一般不会使用
# p1 = Person()
# print(p1)
# test()
# test2()# 也可以为引入的变量使用别名
# 语法:from 模块名 import 变量 as 别名
# from m import test2 as new_test2# test2()
# new_test2()from m import *
# print(_c)# import xxx
# import xxx as yyy
# from xxx import yyy , zzz , fff
# from xxx import *
# from xxx import yyy as zz

2.15 包

# 包 Package
# 包也是一个模块
# 当我们模块中代码过多时,或者一个模块需要被分解为多个模块时,这时就需要使用到包
# 普通的模块就是一个py文件,而包是一个文件夹
#   包中必须要一个一个 __init__.py 这个文件,这个文件中可以包含有包中的主要内容
from hello import a , bprint(a.c)
print(b.d)# __pycache__ 是模块的缓存文件
# py代码在执行前,需要被解析器先转换为机器码,然后再执行
#   所以我们在使用模块(包)时,也需要将模块的代码先转换为机器码然后再交由计算机执行
#   而为了提高程序运行的性能,python会在编译过一次以后,将代码保存到一个缓存文件中
#   这样在下次加载这个模块(包)时,就可以不再重新编译而是直接加载缓存中编译好的代码即可

在这里插入图片描述

2.16 标准库

# 开箱即用
# 为了实现开箱即用的思想,Python中为我们提供了一个模块的标准库
# 在这个标准库中,有很多很强大的模块我们可以直接使用,
#   并且标准库会随Python的安装一同安装
# sys模块,它里面提供了一些变量和函数,使我们可以获取到Python解析器的信息
#   或者通过函数来操作Python解析器
# 引入sys模块
import sys# pprint 模块它给我们提供了一个方法 pprint() 该方法可以用来对打印的数据做简单的格式化
import pprint# sys.argv
# 获取执行代码时,命令行中所包含的参数
# 该属性是一个列表,列表中保存了当前命令的所有参数
# print(sys.argv)# sys.modules
# 获取当前程序中引入的所有模块
# modules是一个字典,字典的key是模块的名字,字典的value是模块对象
# pprint.pprint(sys.modules)# sys.path
# 他是一个列表,列表中保存的是模块的搜索路径
# ['C:\\Users\\lilichao\\Desktop\\resource\\course\\lesson_06\\code',
# 'C:\\dev\\python\\python36\\python36.zip',
# 'C:\\dev\\python\\python36\\DLLs',
# 'C:\\dev\\python\\python36\\lib',
# 'C:\\dev\\python\\python36',
# 'C:\\dev\\python\\python36\\lib\\site-packages']
# pprint.pprint(sys.path)# sys.platform
# 表示当前Python运行的平台
# print(sys.platform)# sys.exit()
# 函数用来退出程序
# sys.exit('程序出现异常,结束!')
# print('hello')# os 模块让我们可以对操作系统进行访问
import os# os.environ
# 通过这个属性可以获取到系统的环境变量
# pprint.pprint(os.environ['path'])# os.system()
# 可以用来执行操作系统的名字
# os.system('dir')
os.system('notepad')

3.序列

列表(list)

- 列表是Python中的一个对象
- 对象(object)就是内存中专门用来存储数据的一块区域
- 之前我们学习的对象,像数值,它只能保存一个单一的数据
- 列表中可以保存多个有序的数据
- 列表是用来存储对象的对象
- 列表的使用:1.列表的创建2.操作列表中的数据

序列(sequence)

- 序列是Python中最基本的一种数据结构
- 数据结构指计算机中数据存储的方式
- 序列用于保存一组有序的数据,所有的数据在序列当中都有一个唯一的位置(索引)并且序列中的数据会按照添加的顺序来分配索引
- 序列的分类:可变序列(序列中的元素可以改变):> 列表(list)不可变序列(序列中的元素不能改变):> 字符串(str> 元组(tuple

3.1 列表

# 创建列表,通过[]来创建列表
my_list = [] # 创建了一个空列表
# print(my_list , type(my_list))# 列表存储的数据,我们称为元素
# 一个列表中可以存储多个元素,也可以在创建列表时,来指定列表中的元素
my_list = [10] # 创建一个只包含一个元素的列表# 当向列表中添加多个元素时,多个元素之间使用,隔开
my_list = [10,20,30,40,50] # 创建了一个保护有5个元素的列表# 列表中可以保存任意的对象
my_list = [10,'hello',True,None,[1,2,3],print]# 列表中的对象都会按照插入的顺序存储到列表中,
#   第一个插入的对象保存到第一个位置,第二个保存到第二个位置
# 我们可以通过索引(index)来获取列表中的元素
#   索引是元素在列表中的位置,列表中的每一个元素都有一个索引
#   索引是从0开始的整数,列表第一个位置索引为0,第二个位置索引为1,第三个位置索引为2,以此类推
my_list = [10,20,30,40,50]# 通过索引获取列表中的元素
# 语法:my_list[索引] my_list[0]
# print(my_list[4])
# 如果使用的索引超过了最大的范围,会抛出异常
# print(my_list[5]) IndexError: list index out of range# 获取列表的长度,列表中元素的个数
# len()函数,通过该函数可以获取列表的长度
# 获取到的长度的值,是列表的最大索引 + 1
print(len(my_list)) # 5

3.2 切片

# 切片
# 切片指从现有列表中,获取一个子列表
# 创建一个列表,一般创建列表时,变量的名字会使用复数
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精']# 列表的索引可以是负数
# 如果索引是负数,则从后向前获取元素,-1表示倒数第一个,-2表示倒数第二个 以此类推
# print(stus[-2])# 通过切片来获取指定的元素
# 语法:列表[起始:结束] 
#   通过切片获取元素时,会包括起始位置的元素,不会包括结束位置的元素
#   做切片操作时,总会返回一个新的列表,不会影响原来的列表
#   起始和结束位置的索引都可以省略不写
#   如果省略结束位置,则会一直截取到最后
#   如果省略起始位置,则会从第一个元素开始截取
#   如果起始位置和结束位置全部省略,则相当于创建了一个列表的副本
# print(stus[1:])
# print(stus[:3])
# print(stus[:])
# print(stus)# 语法:列表[起始:结束:步长] 
# 步长表示,每次获取元素的间隔,默认值是1
# print(stus[0:5:3])
# 步长不能是0,但是可以是负数
# print(stus[::0]) ValueError: slice step cannot be zero
# 如果是负数,则会从列表的后部向前边取元素
print(stus[::-1])

3.3 通用操作

# + 和 *
# +可以将两个列表拼接为一个列表
my_list = [1,2,3] + [4,5,6]# * 可以将列表重复指定的次数
my_list = [1,2,3] * 5# print(my_list)# 创建一个列表
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精','沙和尚','沙和尚']# in 和 not in
# in用来检查指定元素是否存在于列表中
#   如果存在,返回True,否则返回False
# not in用来检查指定元素是否不在列表中
#   如果不在,返回True,否则返回False
# print('牛魔王' not in stus) #True
# print('牛魔王' in stus)# len()获取列表中的元素的个数# min() 获取列表中的最小值
# max() 获取列表中的最大值
arr = [10,1,2,5,100,77]
# print(min(arr) , max(arr))# 两个方法(method),方法和函数基本上是一样,只不过方法必须通过 对象.方法() 的形式调用
# xxx.print() 方法实际上就是和对象关系紧密的函数
# s.index() 获取指定元素在列表中的第一次出现时索引
# print(stus.index('沙和尚'))
# index()的第二个参数,表示查找的起始位置 , 第三个参数,表示查找的结束位置
# print(stus.index('沙和尚',3,7))
# 如果要获取列表中没有的元素,会抛出异常
# print(stus.index('牛魔王')) ValueError: '牛魔王' is not in list
# s.count() 统计指定元素在列表中出现的次数
print(stus.count('牛魔王'))

3.4 修改元素

# 创建一个列表
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精']# print("修改前:",stus)
# 修改列表中的元素
# 直接通过索引来修改元素
stus[0] = 'sunwukong'
stus[2] = '哈哈'
# 通过del来删除元素
del stus[2] # 删除索引为2的元素# print('修改后:',stus)stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精']# print("修改前:",stus)# 通过切片来修改列表
# 在给切片进行赋值时,只能使用序列
# stus[0:2] = ['牛魔王','红孩儿'] 使用新的元素替换旧元素
# stus[0:2] = ['牛魔王','红孩儿','二郎神']
# stus[0:0] = ['牛魔王'] # 向索引为0的位置插入元素
# 当设置了步长时,序列中元素的个数必须和切片中元素的个数一致
# stus[::2] = ['牛魔王','红孩儿','二郎神']# 通过切片来删除元素
# del stus[0:2]
# del stus[::2]
# stus[1:3] = []# print('修改后:',stus)# 以上操作,只适用于可变序列
s = 'hello'
# s[1] = 'a' 不可变序列,无法通过索引来修改
# 可以通过 list() 函数将其他的序列转换为list
s = list(s)
print(s)

3.5 列表方法

# 列表的方法
stus = ['孙悟空','猪八戒','沙和尚','唐僧']
# print('原列表:',stus)# append() 
# 向列表的最后添加一个元素
# stus.append('唐僧')# insert()
# 向列表的指定位置插入一个元素
# 参数:
#   1.要插入的位置
#   2.要插入的元素
# stus.insert(2,'唐僧')# extend()
# 使用新的序列来扩展当前序列
# 需要一个序列作为参数,它会将该序列中的元素添加到当前列表中
# stus.extend(['唐僧','白骨精'])
# stus += ['唐僧','白骨精']# clear()
# 清空序列
# stus.clear()# pop()
# 根据索引删除并返回被删除的元素# result = stus.pop(2) # 删除索引为2的元素
# result = stus.pop() # 删除最后一个
# print('result =',result)# remove()
# 删除指定值得元素,如果相同值得元素有多个,只会删除第一个
# stus.remove('猪八戒')# reverse()
# 用来反转列表
# stus.reverse()# sort()
# 用来对列表中的元素进行排序,默认是升序排列
# 如果需要降序排列,则需要传递一个reverse=True作为参数
my_list = list('asnbdnbasdabd')
my_list = [10,1,20,3,4,5,0,-2]print('修改前',my_list)my_list.sort(reverse=True)
print('修改后',my_list)
# print('修改后:',stus)

3.6 遍历列表

# 遍历列表,指的就是将列表中的所有元素取出来
# 创建列表
stus = ['孙悟空','猪八戒','沙和尚','唐僧','白骨精','蜘蛛精']# 遍历列表
# print(stus[0])
# print(stus[1])
# print(stus[2])
# print(stus[3])# 通过while循环来遍历列表
# i = 0
# while i < len(stus):
#     print(stus[i])
#     i += 1# 通过for循环来遍历列表
# 语法:
#   for 变量 in 序列 :
#       代码块
# for循环的代码块会执行多次,序列中有几个元素就会执行几次
#   没执行一次就会将序列中的一个元素赋值给变量,
#   所以我们可以通过变量,来获取列表中的元素for s in stus :print(s)

练习

# 显示系统的欢迎信息
print('-'*20 , '欢迎使用员工管理系统', '-'*20)
# 创建一个列表,用来保存员工的信息,员工的信息以字符串的形式统一保存到列表
emps = ['孙悟空\t18\t男\t花果山','猪八戒\t28\t男\t高老庄']# 创建一个死循环
while True:# 显示用户的选项print('请选择要做的操作:')print('\t1.查询员工')print('\t2.添加员工')print('\t3.删除员工')print('\t4.退出系统')user_choose = input('请选择[1-4]:')print('-'*62)# 根据用户的选择做相关的操作if user_choose == '1' :# 查询员工# 打印表头print('\t序号\t姓名\t年龄\t性别\t住址')# 创建一个变量,来表示员工的序号n = 1# 显示员工信息for emp in emps :print(f'\t{n}\t{emp}')n += 1elif user_choose == '2':# 添加员工# 获取要添加员工的信息,姓名、年龄、性别、住址emp_name = input('请输入员工的姓名:')emp_age = input('请输入员工的年龄:')emp_gender = input('请输入员工的性别:')emp_address = input('请输入员工的住址:')# 创建员工信息# 将四个信息拼接为一个字符串,然后插入到列表中emp = f'{emp_name}\t{emp_age}\t{emp_gender}\t{emp_address}'# 显示一个提示信息print('以下员工将被添加到系统中')print('-'*62)print('姓名\t年龄\t性别\t住址')print(emp)print('-'*62)user_confirm = input('是否确认该操作[Y/N]:')# 判断if user_confirm == 'y' or user_confirm == 'yes' :# 确认emps.append(emp)# 显示提示信息print('添加成功!')else :# 取消操作print('添加已取消!')elif user_choose == '3':# 删除员工,根据员工的序号来删除员工# 获取要删除的员工的序号del_num = int(input('请输入要删除的员工的序号:'))# 判断序号是否有效if 0 < del_num <= len(emps) :# 输入合法,根据序号来获取索引del_i = del_num - 1# 显示一个提示信息print('以下员工将被删除')print('-'*62)print('\t序号\t姓名\t年龄\t性别\t住址')print(f'\t{del_num}\t{emps[del_i]}')print('-'*62)user_confirm = input('该操作不可恢复,是否确认[Y/N]:')# 判断if user_confirm == 'y' or user_confirm == 'yes' :# 删除元素emps.pop(del_i)# 显示提示print('员工已被删除!')else :# 操作取消print('操作已取消!')else :# 输入有误print('您的输入有误,请重新操作!')elif user_choose == '4':# 退出print('欢迎使用!再见!')input('点击回车键退出!')breakelse :print('您的输入有误,请重新选择!')# 打印分割线print('-'*62)

4.元组

# 元组 tuple
# 元组是一个不可变的序列
# 它的操作的方式基本上和列表是一致的
# 所以你在操作元组时,就把元组当成是一个不可变的列表就ok了
# 一般当我们希望数据不改变时,就使用元组,其余情况都使用列表# 创建元组
# 使用()来创建元组
my_tuple = () # 创建了一个空元组
# print(my_tuple,type(my_tuple)) # <class 'tuple'>my_tuple = (1,2,3,4,5) # 创建了一个5个元素的元组
# 元组是不可变对象,不能尝试为元组中的元素重新赋值
# my_tuple[3] = 10 TypeError: 'tuple' object does not support item assignment
# print(my_tuple[3])# 当元组不是空元组时,括号可以省略
# 如果元组不是空元组,它里边至少要有一个,
my_tuple = 10,20,30,40
my_tuple = 40,
# print(my_tuple , type(my_tuple))my_tuple = 10 , 20 , 30 , 40# 元组的解包(解构)
# 解包指就是将元组当中每一个元素都赋值给一个变量
a,b,c,d = my_tuple# print("a =",a)
# print("b =",b)
# print("c =",c)
# print("d =",d)# 方便元素之间进行交换,如下
a = 100
b = 300
# print(a , b)# 交互a 和 b的值,这时我们就可以利用元组的解包
a , b = b , a# print(a , b)
my_tuple = 10 , 20 , 30 , 40# 在对一个元组进行解包时,变量的数量必须和元组中的元素的数量一致
# 也可以在变量前边添加一个*,这样变量将会获取元组中所有剩余的元素
a , b , *c = my_tuple
a , *b , c = my_tuple
*a , b , c = my_tuple
a , b , *c = [1,2,3,4,5,6,7]
a , b , *c = 'hello world'
# 不能同时出现两个或以上的*变量
# *a , *b , c = my_tuple SyntaxError: two starred expressions in assignment
print('a =',a)
print('b =',b)
print('c =',c)

5.字典(dict)

- 字典属于一种新的数据结构,称为映射(mapping)
- 字典的作用和列表类似,都是用来存储对象的容器
- 列表存储数据的性能很好,但是查询数据的性能的很差
- 在字典中每一个元素都有一个唯一的名字,通过这个唯一的名字可以快速的查找到指定的元素
- 在查询元素时,字典的效率是非常快的
- 在字典中可以保存多个对象,每个对象都会有一个唯一的名字这个唯一的名字,我们称其为键(key),通过key可以快速的查询value这个对象,我们称其为值(value)所以字典,我们也称为叫做键值对(key-value)结构每个字典中都可以有多个键值对,而每一个键值对我们称其为一项(item)
# 字典
# 使用 {} 来创建字典
d = {} # 创建了一个空字典# 创建一个保护有数据的字典
# 语法:
#   {key:value,key:value,key:value}
#   字典的值可以是任意对象
#   字典的键可以是任意的不可变对象(int、str、bool、tuple ...),但是一般我们都会使用str
#       字典的键是不能重复的,如果出现重复的后边的会替换到前边的
# d = {'name':'孙悟空' , 'age':18 , 'gender':'男' , 'name':'sunwukong'}
d = {
'name':'孙悟空' , 
'age':18 , 
'gender':'男' , 
'name':'sunwukong'
}# print(d , type(d))# 需要根据键来获取值
# print(d['name'],d['age'],d['gender'])# 如果使用了字典中不存在的键,会报错
# print(d['hello']) KeyError: 'hello'

5.1 使用

# 创建字典
# 使用{}
# 语法:{k1:v1,k2:v2,k3:v3}# 使用 dict()函数来创建字典
# 每一个参数都是一个键值对,参数名就是键,参数名就是值(这种方式创建的字典,key都是字符串)
d = dict(name='孙悟空',age=18,gender='男') # 也可以将一个包含有双值子序列的序列转换为字典
# 双值序列,序列中只有两个值,[1,2] ('a',3) 'ab'
# 子序列,如果序列中的元素也是序列,那么我们就称这个元素为子序列
# [(1,2),(3,5)]
d = dict([('name','孙悟饭'),('age',18)])
# print(d , type(d))
d = dict(name='孙悟空',age=18,gender='男') # len() 获取字典中键值对的个数
# print(len(d))# in 检查字典中是否包含指定的键
# not in 检查字典中是否不包含指定的键
# print('hello' in d)# 获取字典中的值,根据键来获取值
# 语法:d[key]
# print(d['age'])# n = 'name'
# print(d[n])# 通过[]来获取值时,如果键不存在,会抛出异常 KeyError
# get(key[, default]) 该方法用来根据键来获取字典中的值
#   如果获取的键在字典中不存在,会返回None
#   也可以指定一个默认值,来作为第二个参数,这样获取不到值时将会返回默认值
# print(d.get('name'))
# print(d.get('hello','默认值'))# 修改字典
# d[key] = value 如果key存在则覆盖,不存在则添加
d['name'] = 'sunwukong' # 修改字典的key-value
d['address'] = '花果山' # 向字典中添加key-value# print(d)
# setdefault(key[, default]) 可以用来向字典中添加key-value
#   如果key已经存在于字典中,则返回key的值,不会对字典做任何操作
#   如果key不存在,则向字典中添加这个key,并设置value
result = d.setdefault('name','猪八戒')
result = d.setdefault('hello','猪八戒')# print('result =',result)
# print(d)# update([other])
# 将其他的字典中的key-value添加到当前字典中
# 如果有重复的key,则后边的会替换到当前的
d = {'a':1,'b':2,'c':3}
d2 = {'d':4,'e':5,'f':6, 'a':7}
d.update(d2)# print(d)
# 删除,可以使用 del 来删除字典中的 key-value
del d['a']
del d['b']# popitem()
# 随机删除字典中的一个键值对,一般都会删除最后一个键值对
#   删除之后,它会将删除的key-value作为返回值返回
#   返回的是一个元组,元组中有两个元素,第一个元素是删除的key,第二个是删除的value
# 当使用popitem()删除一个空字典时,会抛出异常 KeyError: 'popitem(): dictionary is empty'
# d.popitem()
# result = d.popitem()# pop(key[, default])
# 根据key删除字典中的key-value
# 会将被删除的value返回!
# 如果删除不存在的key,会抛出异常
#   如果指定了默认值,再删除不存在的key时,不会报错,而是直接返回默认值
result = d.pop('d')
result = d.pop('z','这是默认值')# del d['z'] z不存在,报错
# result = d.popitem()
# result = d.popitem()
# result = d.popitem()
# result = d.popitem()# clear()用来清空字典
d.clear()# print('result =',result)
# print(d)# copy()
# 该方法用于对字典进行浅复制
# 复制以后的对象,和原对象是独立,修改一个不会影响另一个
# 注意,浅复制会简单复制对象内部的值,如果值也是一个可变对象,这个可变对象不会被复制
d = {'a':1,'b':2,'c':3}
d2 = d.copy()
# d['a'] = 100d = {'a':{'name':'孙悟空','age':18},'b':2,'c':3}
d2 = d.copy()
d2['a']['name'] = '猪八戒'print('d = ',d , id(d))
print('d2 = ',d2 , id(d2))

5.2 遍历

# 遍历字典
# keys() 该方法会返回字典的所有的key
#   该方法会返回一个序列,序列中保存有字典的所有的键
d = {'name':'孙悟空','age':18,'gender':'男'}# 通过遍历keys()来获取所有的键
# for k in d.keys() :
#     print(k , d[k])# values()
# 该方法会返回一个序列,序列中保存有字典的左右的值
# for v in d.values():
#     print(v)# items()
# 该方法会返回字典中所有的项
# 它会返回一个序列,序列中包含有双值子序列
# 双值分别是,字典中的key和value
# print(d.items())
for k,v in d.items() :print(k , '=' , v)

6. 集合(set)

- 集合和列表非常相似
- 不同点:1.集合中只能存储不可变对象2.集合中存储的对象是无序(不是按照元素的插入顺序保存)3.集合中不能出现重复的元素
# 集合
# 使用 {} 来创建集合
s = {10,3,5,1,2,1,2,3,1,1,1,1} # <class 'set'>
# s = {[1,2,3],[4,6,7]} TypeError: unhashable type: 'list'
# 使用 set() 函数来创建集合
s = set() # 空集合
# 可以通过set()来将序列和字典转换为集合
s = set([1,2,3,4,5,1,1,2,3,4,5])
s = set('hello')
s = set({'a':1,'b':2,'c':3}) # 使用set()将字典转换为集合时,只会包含字典中的键# 创建集合
s = {'a' , 'b' , 1 , 2 , 3 , 1}# 使用in和not in来检查集合中的元素
# print('c' in s)# 使用len()来获取集合中元素的数量
# print(len(s))# add() 向集合中添加元素
s.add(10)
s.add(30)# update() 将一个集合中的元素添加到当前集合中
#   update()可以传递序列或字典作为参数,字典只会使用键
s2 = set('hello')
s.update(s2)
s.update((10,20,30,40,50))
s.update({10:'ab',20:'bc',100:'cd',1000:'ef'})# {1, 2, 3, 100, 40, 'o', 10, 1000, 'a', 'h', 'b', 'l', 20, 50, 'e', 30}
# pop()随机删除并返回一个集合中的元素
# result = s.pop()# remove()删除集合中的指定元素
s.remove(100)
s.remove(1000)# clear()清空集合
s.clear()# copy()对集合进行浅复制# print(result)
print(s , type(s))

这篇关于Python:数据类型(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974742

相关文章

Zen of Python -Python之禅

在浏览Python官方文档时无意发现了这个彩蛋,只需在终端中import this The Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than compli

Python内置函数oct()详解

Python中的oct()函数是一个内置函数,用于将一个整数转换成它的八进制字符串表示。 函数定义 oct()函数的基本语法如下: oct(x) x:一个整数。 函数返回x的八进制表示,以字符串形式。 基本用法 将整数转换为八进制 number = 64print(oct(number)) # 输出: '0o100' 转换负整数 number = -64print(o

Python筑基之旅-溯源及发展

目录 一、Python的起源 二、Python的版本更替及变化 三、Python的优缺点 四、Python的发展方向 五、Python之禅 六、推荐专栏/主页: 1、Python函数之旅:Functions 2、Python算法之旅:Algorithms 3、个人主页:https://myelsa1024.blog.csdn.net/ ​​​​​​​ 一、Python

Python专题:十六、异常处理(2)

异常的预判和防护 import randomnum = random.randint(1, 100) # 获得一个随机数is_done = False # 是否猜中的标记count = 0 # 玩家猜了几次while not is_done:guess = int(input('请输入一个[1, 100]的整数:'))if guess == num:is_done = Trueelif

理解 Python 中的 `super()` 与 `__init__()` 方法

在 Python 的面向对象编程中,super() 函数和 __init__() 方法是两个非常重要的概念。它们在类的继承和初始化过程中扮演着关键的角色。本文将深入探讨这两个概念的工作原理,并通过示例代码来展示它们的使用。 基本原理 __init__() 方法 __init__() 是一个特殊的方法,也称为类的构造器。当你创建一个类的新实例时,Python 会自动调用这个方法。它通常用于初始

python 合并 pdf

from pypdf import PdfMergerpdfs = ['file1.pdf', 'file2.pdf', 'file3.pdf', 'file4.pdf']merger = PdfMerger()for pdf in pdfs:merger.append(pdf)merger.write("result.pdf")merger.close() 参考 https://stack

Python——IO编程

IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。 比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,

python 脚本压缩文件linux 正常,windows 文件夹/文件名称 被加上了上级文件夹名

场景: php 在调用python 脚本,进行文件压缩(因为php的压缩大文件总是超时),linux/mac 环境文件/文件夹名压缩前后一致,windows 压缩后 文件/文件夹名被改变为 上级 文件夹+原名 原因: windows 和 mac、linux 文件路径的分隔符 不一样 解决: 使用php 自带的分隔符常量DIRECTORY_SEPARATOR,该常量会根据 不同系统,变化

Python简易图书管理系统重构

在本篇课文中,我们将使用Python语言结合MySQL数据库,从零开始构建一个简单的图书管理系统。该系统旨在帮助图书馆管理员轻松管理图书的借阅、归还以及查询图书信息等日常操作。我们将分步介绍需求分析、数据库设计、环境搭建、功能实现等关键环节,并提供详细的源代码示例。 #### **一、需求分析** 图书管理系统的核心功能包括: - 图书录入:允许管理员添加新书到系统。 - 图书查询:提供按书名

python开发的学习路线

I. 基础知识学习 A. Python基础语法         变量和数据类型 学习如何定义变量,理解并使用不同的数据类型(整数、浮点数、字符串、布尔值等)。 掌握数字类型的转换和操作。 熟悉字符串的基本操作,如拼接、切片、替换和查找。                                                                控制流程 掌握条件语句