ps:Python所有的数据都是对象,包括int,float这些都是对象,所以Python万事万物皆对象!!!
1. 基础知识 1.1 变量的定义和使用变量由三部分组成:
- 标识:表示地址,用
id(obj)
获取 - 类型:表示数据类型,用
type(obj)
来获取 - 值:表示具体数据,用
print(obj)
来打印输出
整数的不同进制表示:
- 十进制:默认
- 二进制:以0b开头
- 八进制:以0o开头
- 十六进制:以0x开头
数据类型转换:
- str():将其他类型转换成字符串
- int():将其他类型转换成整数
- float():将其他类型转换成浮点数
- 单行注释
# 单行注释
- 多行注释
"""
多行注释
"""
- 编码声明
#coding:utf-8
#coding:gbk
#encoding=utf-8
#encoding=gbk
1.3 输入
input()函数用接收用户输入,返回值类型为str。
a = int(input("请输入年龄:")); # 用int 将str转换类型
1.4 运算符
- 算术运算符:**, *, /, //, %, +, -
- 位运算符:<<, >>, &, |
- 比较运算符:>, <, >=, <=, ==, !=
- 逻辑运算符:and, or
- 赋值运算符:=
# 单分支结构
if expression:
pass # 占位符,在搭框架的时候用
# 双分支结构
if expression:
pass
else:
pass
# 多分支结构
if expression1:
pass
elif expression2:
pass
elif expression3:
pass
[else:]
pass
# 嵌套if
if expression1:
if expression2:
pass
else:
pass
else:
pass
2.2 循环结构
# while循环
while expression:
pass
# for-in循环
for item in 'python':
pass
for i in range(10):
pass
2.3 流程控制语句
- break语句:用于结束当前循环体
- continue语句:用于结束当次循环
- else语句:
- if … else …
- while … else … 和 for … else …:没有碰到break时执行else
lst=['hello','world',98]
lst2=list(['hello','world',98])
3.1.2 查询
- 获取指定元素的索引:内置函数index()
- 获取单个元素:[index_num]
- 切片:
# 正向:step为正数
[start : stop [: step]]
# 反向:step为负数
[start::step]
3.1.3 增加
- append(element)
- extend(element)
- insert(pos, element)
- 切片
- remove(element):删除第一个element元素
- pop([index]):删除指定索引位置的元素,若不指定,则删除最后一个元素
- 切片
- del lst:删除列表
- clear():清空列表
- 单个
- 切片
- sort()方法:sort(lst, reverse=True),默认升序排列,无返回值
- sorted()内置函数:sorted(lst, reverse=True),返回排好序的列表
scores = {"张三":100, "李四":98}
student = dict(name='jack',age=20)
d = {}
3.2.2 查询
- [key]
- get(key[, default])方法
scores['Jack'] = 90
3.2.4 删除
del scores['张三']
3.2.5 获取字典视图
- keys():返回一个列表,存储所有的key
- values():返回一个列表,存储所有的value
- items():返回一个列表,存储所有的(key, value)元组
内置函数zip()用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表。
# 内置函数zip()
items = ['fruits','books','others']
prices = [96,78,85]
d = {item.upper():price for item,price in zip(items,prices)}
print(d)
3.3. 元组
元组是不可变序列,没有增、删、改
的 *** 作。
t1 = ('python','hello',90)
t2 = tuple('python','hello',90)
t3 = (10,) # 只包含一个元素需要使用逗号
3.3.2 遍历
可以用for-in遍历。
3.4. 集合集合是没有value的字典,因为字典中的key不允许重复,所以集合也不允许有重复元素。
3.4.1 创建s1 = {'python','hello',90}
s2 = set(range(6))
3.4.2 增加
- add():一次添加一个元素
- update():至少添加一个元素
- remove(element):删除一个指定元素
- discard(element):删除一个指定元素
- pop():删除任意一个元素
- clear():清空
s = {10, 20, 30, 40}
s1 = {20, 10, 40, 30}
s2 = {10, 30}
s3 = {30, 50}
print(s2.issubset(s)) # True
print(s3.issubset(s)) # False
print(s.issuperset(s2)) # True
print(s.issuperset(s3)) # False
s4 = {60, 70, 80}
print(s.isdisjoint(s1)) # False
print(s.isdisjoint(s2)) # False
print(s.isdisjoint(s4)) # True
3.4.5 集合间的数学 *** 作
# 交集:intersection() 或 &
s1 = {10, 20, 30}
s2 = {23, 30, 20}
print(s1.intersection(s2)) # {20, 30}
print(s1 & s2) # {20, 30}
# 并集:union() 或 |
print(s1.union(s2)) # {20, 23, 10, 30}
print(s1 | s2) # {20, 23, 10, 30}
# 差集:difference() 或 -
s1 = {10, 20, 30, 40}
s2 = {20, 30, 50}
print(s1.difference(s2)) # {40, 10}
print(s1 - s2) # {40, 10}
# 对称差集:symmetric_difference() 或 ^
s1 = {10, 20, 30, 40}
s2 = {20, 30, 50}
print(s1.symmetric_difference(s2)) # {40, 10, 50}
print(s1 ^ s2) # {40, 10, 50}
4. 字符串
4.1 驻留机制
在python中字符串是不可变的字符序列,python机制有一个驻留池,用于存放字符串,当创建字符串时,编译器会把字符串的地址赋给新创建的变量。这个类似于c++的常量池。
a='Python'
b='Python'
c='python'
print('a:',a,id(a)) # a: Python 2834106576176
print('b:',b,id(b)) # b: Python 2834106576176
print('c:',c,id(c)) # c: python 2752480713056
4.2 查询方法
- index(substr):查询substr第一次出现的位置,若不存在,报错
- rindex(substr):查询substr最后一次出现的位置,若不存在,报错
- find(substr):查询substr第一次出现的位置,若不存在,返回-1
- rfind(substr):查询substr最后一次出现的位置,若不存在,返回-1
- upper()
- lower()
- swapcase():大写变小写,小写变大写
- capitalize():首字符大写,其余小写
- titile():每个单词首字符大写,其余小写
4.4 对齐方法转换之后返回新字符串
- center(宽度,填充符):居中对齐,指定填充符,默认空格填充。
- ljust(宽度,填充符):左对齐,指定填充符,默认空格填充。
- rjust(宽度,填充符):右对齐,指定填充符,默认空格填充。
- zfill(宽度 ):右对齐,零填充
s='hello,Python'
print(s.center(20,'*')) # ****hello,Python****
print(s.ljust(20,'*')) # hello,Python********
print(s.ljust(10,'*')) # hello,Python
print(s.ljust(20)) # hello,Python
print(s.rjust(20,'*')) # ********hello,Python
print(s.rjust(20)) # hello,Python
print(s.rjust(10)) # hello,Python
print(s.zfill(20)) # 00000000hello,Python
print('-9010'.zfill(8)) # -0009010
4.5 切分方法
- split(sep=’ ', maxsplit=-1):从左边开始切分,返回一个列表
- rsplit(sep=’ ', maxsplit=-1):从右边开始切分,返回一个列表
s='hello world python'
print(s.split()) # ['hello', 'world', 'python']
s1='hello|world|python'
print(s1.split('|')) # ['hello', 'world', 'python']
print(s1.split('|',maxsplit=1)) # ['hello', 'world|python']
s='hello world python'
print(s.rsplit()) # ['hello', 'world', 'python']
s1='hello|world|python'
print(s1.rsplit('|')) # ['hello', 'world', 'python']
print(s1.rsplit('|',maxsplit=1)) # ['hello|world', 'python']
4.6 替换和合并方法
- replace(old, new, count=None):count指定最大替换次数
- join(iterable):将列表或元组中的字符串合并成一个字符串
s = 'hello,python,python,python'
print(s.replace('python', 'c++')) # hello,c++,c++,c++
s = 'hello,python,python,python'
print(s.replace('python', 'c++', 2)) # hello,c++,c++,python
lst = ['hello', 'java', 'python']
print('|'.join(lst)) # hello|java|python
print(''.join(lst)) # hellojavapython
t = ('hello', 'java', 'python')
print('|'.join(t)) # hello|java|python
print(''.join(t)) # hellojavapython
print('*'.join('Python')) # P*y*t*h*o*n
4.7 拼接方法
- join():跟合并是一样的,官方推荐拼接用join(),而不用’+'。
4.8 比较 *** 作原因:String对象是定长对象,一旦创建,长度就不可变化,若是使用+号连接两个字符串,则会新开辟一段长度总和长度的内存,再将两个字符串memcpy进去。如果要连接N个String对象,则要进行N-1次内存申请和拷贝。join() 方法对于连接一个list或tuple中的元素非常有效,它会先统计所有元素的长度,申请内存,然后拷贝。
>, >=, <, <=, ==, !=
# 底层遍历两个字符串的每个字符,调用ord()得到ascii码值,比较两者的码值。
# 与ord()对应的是chr(),chr()将ascii码值转换为对应的字符。
==
和is
的区别:
- == 比较的是字符串的值
- is 比较的是字符串的id
有两种方法:
- % 作占位符
- {} 作占位符
name = '张三'
age = 20
print('我叫%s,今年%d岁' % (name, age)) # 我叫张三,今年20岁
print('我叫{0},今年{1}岁了'.format(name, age)) # 我叫张三,今年20岁了
print(f'我叫{name},今年{age}岁!') # 字符串前加f代表格式化字符串
设置宽度和精度:
print('%10d' % 99) # 宽度
print('0123456789')
print('%.3f'%3.1415926) # 保留小数
print('%10.3f'%3.1415926)
# 99
# 0123456789
# 3.142
# 3.142
print('{0:.3}'.format(3.1415926)) # :.3表示一共是三位数,0代表的是format中的第0位
print('{0:.3f}'.format(3.1415926)) # :.3f表示三位小数
print('{0:10.3f}'.format(3.1415926)) # 同时设置宽度和精度
# 3.14
# 3.142
# 3.142
4.10 编码转换
- 编码:将字符串转换位二进制数据
- 解码:将二进制数值转换成字符串类型
s='天涯共此时'
print(s.encode(encoding='GBK')) # 一个中文占两个字节
print(s.encode(encoding='UTF-8')) # 一个中文占三个字节
# b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
# b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
#解码
byte=b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
print(byte.decode(encoding='GBK'))
byte=b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
print(byte.decode(encoding='UTF-8'))
# 天涯共此时
# 天涯共此时
5. 函数
5.1 函数的参数传递
参数分为不可变类型和可变类型:
- 不可变类型:包括数字,字符串,元组,不可变集合。在函数体内的修改不会影响实参的值。
- 可变类型:包括列表,字典。在函数体内的修改会影响实参的值。
Python的函数参数传递是引用传递
,记住这一点,我们来解决下面的三个问题:
问题1:在函数内部,针对参数使用 赋值语句,会不会影响调用函数时传递的 实参变量?——不会!
- 无论传递的参数是 可变 还是 不可变
def demo(num,num_list):
print('函数内部的代码')
# 在函数内部,针对参数使用赋值语句,不会修改到外部的实参变量
num = 100
num_list = [1,2,3] # 赋值语句实际上修改了局部变量num_list的引用
print(num)
print(num_list)
print('函数执行完成')
gl_num = 90
gl_list = [4,5,6]
demo(gl_num,gl_list)
print(gl_num)
print(gl_list)
输出:
函数内部的代码
100
[1, 2, 3]
函数执行完成
90
[4, 5, 6]
问题2:如果传递的参数是 可变类型,在函数内部,使用 方法 修改了数据的内容,同样会影响到外部的数据
def demo(num_list):
print('函数内部的代码')
# 使用方法修改列表的内容
num_list.append(9) # 没修改局部变量num_list的引用
print(num_list)
print('函数执行完成')
gl_list = [1,2,3]
demo(gl_list)
print(gl_list)
输出:
函数内部的代码
[1, 2, 3, 9]
函数执行完成
[1, 2, 3, 9]
问题3:在
Python
中,列表变量调用+=
本质上是在执行列表变量的extend
方法,不会修改变量的引用。
def demo(num,num_list):
print('函数内部的代码')
# num += num + num
num += num
# num_list += num_list
num_list += num_list
print(num)
print(num_list)
print('函数执行完成')
gl_num = 9
gl_list = [1,2,3]
demo(gl_num,gl_list)
print(gl_num)
print(gl_list)
输出:
函数内部的代码
18
[1, 2, 3, 1, 2, 3]
函数执行完成
9
[1, 2, 3, 1, 2, 3]
5.2 函数的返回值
- 如果没有返回值,return 可以不写
- 如果返回一个值,返回的类型是原值类型
- 如果返回多个值,返回的类型是元组
- 个数可变的位置参数
- 位置参数的结果是一个元组
- 一个函数最多只能有一个位置参数
def fun(*args):
print(args)
fun(10) # (10,)
fun(10,20,30) # (10, 20, 30)
- 个数可变的关键字形参
- 关键字形参的结果是一个字典
- 一个函数最多只能有一个关键字参数
def fun(**kwargs):
print(kwargs)
fun(a=10)
fun(a=10,b=20,c=30)
既有个数可变的位置形参,也有个数可变的位置形参时,个数可变的位置形参要放在个数可变的关键字形参之前
上面简单介绍了个数可变的位置参数和个数可变的关键字参数,其实这个传参过程是元组和字典的拆包和装包
过程:
- 装包:把传递的参数,包装成一个集合,称之为“装包”。
- 拆包:把集合参数,再次分解成单独的个体,称之为“拆包”。
下面我们来看看例子:
def mySum(a,b,c,d):
print(a+b+c+d)
def test(*args):
print(args)
# 拆包,将元组args拆分成多个数字
print(*args)
# mySum(args) # 错误,相当于将元组args传给了参数a
mySum(args[0],args[1],args[2],args[3]) # 这样写比较繁琐
mySum(*args) # 拆包传参,更加简洁
# 将多个数字装到一个元组args中,称为装包
test(1,2,3,4)
'''
输出:
(1, 2, 3, 4)
1 2 3 4
10
10
'''
def mySum1(a,b):
print(a)
print(b)
def test1(**kwargs):
print(kwargs)
# 拆包
# 应该使用 ** 进行拆包 *** 作
# 拆完之后就是a=1,b=2
# print(**kwargs) # 错误,这里相当于执行print(a=1,b=2),显然语法不对
# mySum1(kwargs) # 错误,相当于将字典kwargs传给了参数a
mySum1(a=1,b=2) # 这样写比较繁琐
mySum1(**kwargs) # 拆包传参,更加简洁
# 将多个关键字参数装到一个字典kwargs中,称为装包
test1(a=1,b=2)
'''
输出:
{'a': 1, 'b': 2}
1
2
1
2
'''
拆包装包的应用:
def demo(*args,**kwargs):
print(args)
print(kwargs)
# 元组变量/字典变量
gl_nums = (1,2,3)
gl_dict = {"name":"小明","age":18}
demo(gl_nums,gl_dict) # 这里传的都是元组变量
print('-------------')
# 拆包语法,简化元组变量/字典变量的传递
demo(*gl_nums,**gl_dict) # 使用拆包,相当于调用demo(1,2,3,name='小明',age=18)
print('-------------')
demo(1,2,3,name='小明',age=18)
输出:
((1, 2, 3), {'name': '小明', 'age': 18})
{}
-------------
(1, 2, 3)
{'name': '小明', 'age': 18}
-------------
(1, 2, 3)
{'name': '小明', 'age': 18}
5.4 变量的作用域
- 局部变量:在函数内定义的变量,只有函数内部有效,函数外不能访问。如果使用global声明,这个变量就会变成全局变量,在函数外部也能访问。
- 全局变量:函数体外定义的变量,可以作用于函数内外。
注:Python不能在函数内部修改全局变量的值,除非函数内部使用global声明。
num = 10
def f1():
num = 99 # 这里实际上是在函数内部定义了一个局部变量,不是函数外的num全局变量
print(num)
def f2():
print(num)
f1() # 输出99
f2() # 输出10
num = 10
def f1():
global num # 这里声明了使用函数外的全局变量num,所以这里能够修改num全局变量
num = 99
print(num)
def f2():
print(num)
f1() # 输出99
f2() # 输出99
6. 异常
6.1 常见异常类型
6.2 异常处理机制
6.2.1 try…except
6.2.2 try…except…else
6.2.3 try…except…else…finally
6.2.4 traceback模块
7. 类和对象
7.1 类的创建和对象的创建
类也是一个对象,称为类对象
,在运行时加载到内存中,创建对象之后称为实例对象
。
类由以下四个部分组成:
- 类属性:
类中方法外
的变量成为类属性,为该类的所有对象
所共享。 - 实例方法:由对象调用,方法的第一个参数默认是
self
,构造方法
和析构方法
也属于实例方法。 - 类方法:使用
@classmethod
修饰的方法。使用类名和对象名访问,有一个cls参数,代表定义类方法的类,通过cls 参数
可以访问类属性
。由于没有self参数
,所以类方法是无法访问成员变量
的。类方法中可以调用构造函数
创建对象。 - 静态方法:使用
@staticmethod
修饰的方法。使用类名和对象名访问的方法,没有self参数
,所以无法访问类的成员变量
,也没有cls参数
,所以也无法访问类变量
。静态方法和定义它的类没有直接关系。
class Student:
native_place = "吉林" # 类属性
# 构造方法
def __init__(self,name,age):
self.name = name # self.name称为实例属性
self.age = age
# 析构方法,在对象被销毁之前自动调用
def __del__(self):
print('===析构函数===')
# 实例方法
def eat(self):
print("学生在吃饭")
# 静态方法
@staticmethod
def method(): # 没有默认的self参数,所以静态方法不能使用类的属性和方法
print("我使用了静态方法")
# 类方法
@classmethod
def cm(cls): # 没有
print("我使用了类方法")
print(id(Student)) # 3005583791640
print(type(Student)) #
print(Student) #
print('-----------')
# 创建Student类的对象
stu1 = Student('张三',20)
print(id(stu1)) # 1301185945840
print(type(stu1)) #
print(stu1) # <__main__.Student object at 0x0000012EF4B9E0F0>
stu1.eat()
print(stu1.name)
print(stu1.age)
print('-------------')
Student.eat(stu1) # 相当于把stu1这个对象引用传递给eat方法的self
# 类属性的使用方式
print(Student.native_place) # 吉林
stu2 = Student('李四',30)
print(stu1.native_place) # 吉林
print(stu2.native_place) # 吉林
Student.native_place = '天津'
print(stu1.native_place) # 天津
print(stu2.native_place) # 天津
print('----------类方法的使用方式----------')
Student.cm()
print('----------静态方法的使用方式----------')
Student.method()
# 主动删除两个对象,del之前也会自动调用__del__析构函数
del stu1
del stu2
7.1.1 属性的获取机制
class Tool(object):
# 定义类属性
count = 0
def __init__(self,name):
self.name = name
# 让类属性+1
Tool.count += 1
tool1 = Tool('斧头')
tool2 = Tool('榔头')
tool3 = Tool('水桶')
print("工具对象总数 %d" % tool3.count)
print("===> %d" % Tool.count)
print("------------------------")
tool3.count = 99
print("工具对象总数 %d" % tool3.count)
print("===> %d" % Tool.count)
'''
输出:
工具对象总数 3
===> 3
------------------------
工具对象总数 99
===> 3
'''
7.1.2 单例设计模式
- 目的:让类创建的对象,在系统中
只有唯一的一个实例
- 每一次执行
类名()
返回的对象,内存地址都是相同的
class MusicPlayer(object):
# 记录第一个被创建对象的引用
instance = None
def __new__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)
"""
输出:
<__main__.MusicPlayer object at 0x000002BEF38999B0>
<__main__.MusicPlayer object at 0x000002BEF38999B0>
"""
7.2 动态绑定属性和方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(self.name + '在吃饭')
stu1 = Student('张三', 30)
stu2 = Student('李四', 40)
stu2.gender = '男'
print(stu1.name, stu1.age) # 张三 30
print(stu2.name, stu2.age, stu2.gender) # 李四 40 男
def show():
print('定义在类之外,函数')
stu1.show = show
stu1.show() # 定义在类之外,函数
8. 面向对象的三大特征
- 封装:提高程序的安全性。
- 在Python中没有专门的
权限修饰符
,如果该属性不希望在类外部被访问,前边使用两个"_"
。
- 在Python中没有专门的
- 继承:提高程序的复用性
- 多态:提高程序的可扩展性和可维护性
class Student:
def __init__(self,name,age):
self.name = name
self.__age = age
def show(self):
print(self.name,self.__age)
stu = Student('张三',20)
stu.show() # 张三 20
print(stu.name) # 张三
# print(stu.__age) # AttributeError: 'Student' object has no attribute '__age'
print(dir(stu)) # dir([object]) 返回模块的属性列表,stu的属性列表包含'_Student__age'
print(stu._Student__age) # 20 在类的外部也可以访问,但不建议访问
8.2 继承
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return '我的名字是{0},今年{1}岁了'.format(self.name,self.age)
stu = Student('张三',20)
print(dir(stu))
# __str__()方法用于对stu对象的描述,重写之前是输出stu的地址
print(stu) # 我的名字是张三,今年20岁了
8.2.1 父类的私有属性和私有方法
- 子类对象 不能 在自己的方法内部,直接 访问 父类的 私有属性 或 私有方法
- 子类对象 可以通过 父类的 公有方法 间接 访问到 私有属性 或 私有方法
- 私有属性、方法 是对象的隐私,不对外公开,外界 以及 子类 都不能直接访问
- 私有属性、方法 通常用于做一些内部的事情
问题1:如果 不同的父类 中存在 同名的方法,子类对象 在调用方法时,会调用 哪一个父类中的方法呢?
Python中的MRO
——方法搜索顺序
:
- Python中针对类提供了一个
内置属性
__mro__可以查看方法搜索顺序 - MRO时
method resulution order
,主要用于在多继承时判断方法、属性的调用路径
- 在搜索方法时,是按照
__mro__
的输出结果从左至右
的顺序查找的 - 如果在当前类中
找到方法
,就直接执行,不再搜索
- 如果
没有找到,就查找下一个类
中是否右对应的方法,如果找到,就直接执行,不再搜索
- 如果找到最后一个类,还没有找到方法,程序报错
- 在搜索方法时,是按照
class A(object):
def test(self):
print('A----test方法')
def demo(self):
print('A----demo方法')
class B(object):
def test(self):
print('B----test方法')
def demo(self):
print('B----demo方法')
class C(B,A):
pass
print(C.__mro__)
c = C()
c.test()
c.demo()
"""
输出:
(, , , )
B----test方法
B----demo方法
"""
8.3 多态
8.4 特殊属性和特殊方法
a = 20
b = 100
c = a + b # 两个整数类型的对象的相加 *** 作
d = a.__add__(b) # 底层调用了__add__方法
print(c) # 120
print(d) # 120
# 自定义对象的相加
class Student:
def __init__(self, name):
self.name = name
# 重写__add__方法,实现自定义对象的相加
def __add__(self, other):
return self.name + other.name
# 重写len方法,返回对象的长度
def __len__(self):
return len(self.name)
stu1 = Student('张三')
stu2 = Student('李四')
s = stu1 + stu2
print(s) # 张三李四
s = stu1.__add__(stu2)
print(s) # 张三李四
print('---------------')
lst = [11,22,33,44]
print(len(lst)) # 4
print(lst.__len__()) # 4 底层调用
print(len(stu1)) # 2
class Person(object):
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id值为:{0}'.format(id(cls)))
obj = super().__new__(cls)
print('创建的对象的id为:{0}'.format(id(obj)))
return obj
def __init__(self, name, age):
print('__init__被调用了,self的id值为:{0}'.format(id(self)))
self.name = name
self.age = age
print('object这个类对象的id为:{0}'.format(id(object))) # object这个类对象的id为:1874967952
print('Person这个类对象的id为:{0}'.format(id(Person))) # Person这个类对象的id为:2561543033320
# 创建Person类的实例对象
p1 = Person('张三',20)
print('p1这个Person类的实例对象的id为:{0}'.format(id(p1)))
# __new__被调用执行了,cls的id值位2561543033320
# 创建的对象的id位:2561549439440
# __init__被调用了,self的id值为:2561549439440
# p1这个Person类的实例对象的id为:2561549439440
8.5 类的赋值和浅拷贝
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu=cpu
self.disk=disk
#变量的赋值,同一个实例对象CPU()赋值给两个变量cpu1、cpu2
cpu1=CPU()
cpu2=cpu1
print(cpu1,id(cpu1)) # 5144
print(cpu2,id(cpu2)) # 5144
#类有浅拷贝
print('--------------')
disk=Disk()
computer=Computer(cpu1,disk)
#浅拷贝
import copy
computer2=copy.copy(computer)
print(computer,computer.cpu,computer.disk) # E048 8DD8 E0B8
print(computer2,computer2.cpu,computer2.disk) # E0F0 8DD8 E0B8
print('------------------------------')
#深拷贝
computer3=copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk) # E048 8DD8 E0B8
print(computer3,computer3.cpu,computer3.disk) # E128 E3C8 E9B0
9. 模块
模块就是.py文件。
9.1 导入模块import moduleName [as anotherName]
from moduleName import 函数/变量/类
9.2 __name__属性
main.py模块:
def say_hello():
print("hello")
# 如果直接执行模块,__main__
if __name__ == "__main__":
print(__name__)
# 文件被导入时,能够直接执行的代码不需要被执行
print("小明开发的模块")
say_hello()
"""
输出:
__main__
小明开发的模块
hello
"""
test_import.py模块:
import main
print("-" * 50)
"""
输出:
--------------------------------------------------
"""
10. 包
请看博主的另一篇文章Python常用内置模块使用
12. eval()函数
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)