class Money:
pass
one = Money()
# 通过对象动态添加
one.age = 19
print(one.age)
class Money:
def __init__(self):
self.name = 'vth'
def handler(self):
self.hahaha = '222'
one = Money()
print(one.name)
one.age = 19
print(one.age)
one.handler()
print(one.hahaha)
其实self指代的就是对象。所以,通过类中的方法给对象增加属性的方式,本质上也是通过对对象动态添加属性的方法来做到的。
添加好属性的内存图大概长这样(实际不是,当前先这么理解即可)

查询很简单,咱们其实已经做过了。
在"一"中,我们通过对象.属性,和self.属性的方式已经查询过了。一定要牢记,self.属性实际上也是对象.属性.
先回顾一下数据结构课程中讲过的原地修改与非原地修改。
原地修改就是在当前的容器地址上直接操作,即操作前后不改变内存地址。
这在python的基本数据类型中是不可能的,因为python所有东西都是对象,如果这个对象支持原地修改,那可以原地修改。如果不支持,那就不行。
python中的基本数据类型是不支持原地修改的。
在python中,所有的赋值操作都是不支持原地修改的。
修改的代码和新增的代码并没有什么不一样。只是在后台,python解释器会先看对象是否已经有了这个属性,如果已经有,你再进行赋值操作,那就是修改(非原地修改)。如果没有,则是新增。
class Money:
def __init__(self):
self.name = 'vth'
print(id(self.name))
one = Money()
# 这就是修改, 因为对象此时已经有了name属性
one.name = 'dada'
print(one.name)
print(id(one.name))
输出:
4455563504
dada
4455559088
而且我们可以通过id查询看到,这确实是非原地修改。
在python中,原地修改只能通过对象自身的方法来进行。
比如列表,对象.属性.append(xxx),这样就是原地修改。原地修改不会改变指向。
class Money:
def __init__(self):
self.names = ['vth']
print(id(self.names))
one = Money()
# 这就是原地修改,调用的是对象本身的方法
one.names.append('ygm')
print(id(one.names))
print(one.names)
输出:
4448128896
4448128896
['vth', 'ygm']
原地修改的内存图大概是这样的:

和删除普通的变量没有什么区别。
直接用del进行删除就好了。
class Money:
def __init__(self):
self.names = ['vth']
print(id(self.names))
one = Money()
del one.names
print(one.names)
输出:
4512014208
Traceback (most recent call last):
File "/Users/testtest/PycharmProjects/learnML/test.py", line 7, in <module>
print(one.names)
AttributeError: 'Money' object has no attribute 'names'
好问题。这里指的是:查看对象所属的所有的属性(可以理解为,查看对象这一片内存空间之上的所有属性)。
class Demo:
pass
d = Demo()
# 查看对象所属的所有属性
print(d.__dict__)
d.age = 18
print(d.__dict__)
输出:
{}
{'age': 18}
除了他们是同一个类创建出来的外,没别的啥关系。
即,每创建一个对象,都会开辟一片自己的内存空间,用来存储所属自己对象的属性。
p1, p2两个对象,p2不能通过点运算符访问p1中的属性。