0 定义类
class Money:
pass
print(Money)
# 根据这个类, 创建(实例化)一个对象
one = Money()
print(one)
执行结果: 后面的 0x000… 表示所在的地址
类也可以进行赋值操作
class Money:
pass
print(Money.__name__)
xxx = Money
print(xxx.__name__)
执行结果:
对象.__class__
:打印出对象
class Money:
pass
one = Money()
print(one)
print(one.__class__)
执行结果:
图解上述流程:
1. 给类添加属性
对象.__dict__:
打印属性
# 1. 定义一个类
class Person:
pass
# 2. 根据类, 创建一个对象
p = Person()
# 3. 给 p 对象, 增加一些属性
p.age = 18
p.height = 180
# 4. 验证是否有添加成功
print(p.age)
print(p.__dict__) # 打印出对应的属性和值
执行结果:
图解上述过程:
2. 修改属性值
class Person:
pass
p = Person()
p.age = 18
p.height = 180
p.age = 123
print(p.age)
执行结果:
图解: 首先会在内存空间新开辟一块存放 123
, 然后将 age
指向 123
,完成修改
3. 打印未创建的属性
class Person:
pass
p = Person()
p.age = 18
p.height = 180
p.age = 123
print(p.age)
print(p.sex)
执行结果: 记住报错形式
id():
可以打印内存地址
class Person:
pass
p = Person()
p.pets = ["小花", "小黑"]
print(p.pets, id(p.pets))
p.pets = [1, 2]
print(p.pets, id(p.pets))
执行结果: 地址不同,说明开辟了不同的地址空间
class Person:
pass
p = Person()
p.pets = ["小花", "小黑"]
print(p.pets, id(p.pets))
# 这里 append 不是修改操作,是访问操作
p.pets.append("小黄")
print(p.pets, id(p.pets))
执行结果: 执行结果相同,说明是在同一地址空间进行操作
两个不同对象之间的属性,不可以相互访问:
class Person:
pass
# 2. 根据类, 创建一个对象
p1 = Person()
p2 = Person()
p1.age = 18
p2.address = "上海"
print(p1.address)
执行结果:
图解:
4. 删除属性
# 1. 定义一个类
class Person:
pass
# 2. 根据类, 创建一个对象
p = Person()
p.age = 18
# 删除属性
del p.age
print(p.age)
执行结果:
5. 类属性创建
5.1 第一种方式
class Money:
pass
# 前面讲到增删属性的方式
# one = Money()
# one.age = 10
# one.age = 18
# 创建类属性
Money.count = 1
Money.age = 18
Money.num = 666
print(Money.count)
print(Money.__dict__)
执行结果:
图解: 类中创建了一个 count
,并创建了一个 1
,count
指向 1
5.2 第二种方式
# 在类内部创建属性
class Money:
age = 18
count = 1
num = 666
print(Money.age)
print(Money.count)
print(Money.num)
执行结果:
5.2.1 通过对象来访问类属性
class Money:
age = 18
count = 1
num = 666
one = Money()
print(one.age)
print(one.count)
print(one.num)
print(one.__dict__)
Python 查找机制
:优先到对象自身去查找属性,如果没有找到,则根据__class__找到对象对应的类,到这个类里面查找
执行结果:
对象.__class__
:存储当前对象所指向的类
class Test:
sex = "男"
class Money:
age = 18
count = 1
num = 666
one = Money()
one.__class__ = Test
print(one.__class__)
print(one.sex)
print(one.age)
执行结果: 可以看到,当修改了类所指向的对象后,不能在访问之前对象的属性,而可以访问新指向的类对象的属性
图解:
5.2.2 现在给对象增加一个属性
class Test:
sex = "男"
class Money:
age = 18
count = 1
num = 666
one = Money()
# 给对象增加一个属性
one.sex = "女"
one.__class__ = Test
print(one.__class__)
print(one.sex)
执行结果: 验证了优先在自身对象内找相关属性,没有,再到 __class__
对应的类中找属性
图解:
6. 修改类的属性
class Money:
age = 18
count = 1
num = 666
Money.age = 22
print(Money.age)
执行结果:
注:
不能通过对象修改类的属性,假如有一个对象:one
,one.age= 5
,显然,这样是给 one
对象增加或者修改 age
属性,并不影响类属性
class Money:
age = 18
count = 1
num = 666
one = Money()
print(Money.age)
one.age = 20
print(one.__dict__)
print(Money.age)
执行结果: 可以看到 one
对象中增加了一个属性,但并未修改类中的属性值
7. 删除类的属性
注: 只能删除直系属性,不能通过对象删除类的属性
class Money:
age = 18
count = 1
num = 666
one = Money()
del one.age
print(one.age)
执行结果: 错误结果为 one 中 没有 age 这个属性
8. 属性的内存存储
class Money:
pass
one = Money()
one.age = 18
one.name = "future"
one.sex = "男"
print(one.__dict__)
执行结果: 可以看到对象创建的属性都保存在 __dict__
这个字典中
图解:
8.1 直接修改对象.__dict__属性
class Money:
pass
one = Money()
one.__dict__ = {"name":"future", "age":18}
print(one.age)
print(one.__dict__)
执行结果:
8.2 类的__dict__属性
注: 类的__dict__
属性是只读属性,不能够修改,而对象中的__dict__
属性是可以修改的
class Money:
age = 18
name = "Sz"
one = Money()
print(Money.__dict__)
执行结果:
图解:
class Money:
age = 18
name = "sz"
# 尝试通过 __dict__ 来修改类的属性
Money.__dict__ = {"sex": "男"}
Money.__dict__["age"] = 20
print(Money.age)
print(Money.__dict__)
执行结果: 表示是只读的,不可写
9. 总结
- 这行代码会不会报错?
- 如果不会报错结果是什么?
class Person:
age = 10
pass
p = Person()
p.age += 5
# p.age = p.age + 5
# p.age = 15
print(Person.age)
print(p.age)
执行结果:
执行流程: p.age += 5 => p.age = p.age + 5,实际上是查询操作并在 Person
对象中创建 age
属性,即首先通过类查询 age
的值为 10
,再通过 + 5
,得到 15
,实现 age
属性的创建,所以打印出的结果在 Person
对象中的值为 15
, 在类中的结果为 10
10. 补充
__slots__
:限制对象添加的属性
class Person:
# 表示后面创建的对象只能添加 age 和 num 属性
__slots__ = ["age", "num"]
pass
p = Person()
p.age = 10
p.num = 20
p.sex = "男"
执行结果: