调用类 ====>产生类的对象,该对象也可以成为类的一个实例,调用类的过程也称为类的实例化
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self)
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
最后一行代码就是类的实例化,那么这行代码做了哪些事,我们再来回顾下
我们可以使用类名加.dict方法,查看类的名称空间,那么对象的名称空间能不能查看呢?
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name # 把name这个属性放进对象的名称空间中
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self)
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
print(stu1.__dict__)
在定义类的阶段产生类的名称空间,那么什么时候产生对象的名称空间呢?你要先告诉我什么时候产生对象,只有在调用类的时候才会产生对象,这个时候就会产生出对象的名称空间,有了名称空间就是把对象存好了,但是存不是目的,我们目的是取
print(stu1.__dict__['name'])
毫无疑问,这样肯定是可以的,但是我们还有更好的方法
print(stu1.name)
现在我们定义的类做一下修改
class DeepshareStudent:
school = 'deepshare'
name = 'aaaaaaaaaa'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self)
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
现在有两个name,我再执行以下代码,打印的结果是什么呢
print(stu1.name)
很明显我用对象找他的独有的name属性 就应该从init中找name
但是,如果init函数中没有呢?
print(stu1.school)
这个对象stu1会先从他自己对象的名称空间中找school这个属性,但是他发现没有这个属性,那就后退一级,往类的名称空间中找,注意对象的名称空间和类的名称空间不是一个概念,接下来我们会说明这个问题
如果类的名称空间中没有,他还会往上找吗?
school = 'deepshare'
class DeepshareStudent:
name = 'aaaaaaaaaa'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self)
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
print(stu1.school)
肯定是不能的,写代码的时候Pycharm就会有错误的提示了,现在school是定义在全局,与对象stu1没有任何关系
我们再来看一下代码
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self)
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
print(DeepshareStudent.__dict__)
print(id(DeepshareStudent.__dict__))
print(stu1.__dict__)
print(id(stu1.__dict__))
print(id(stu2.__dict__))
我现在造了两个对象stu1和stu2,打印结果可以说明,他们分别有自己的内存空间,类也有自己的内存空间,那么这之间有什么关系呢?
他们三部分是完全独立的,没有包含与被包含的关系,只不过用对象点属性做属性查找的时候先从对象的名称空间中查找,如果能够找到,就是使用对象的名称空间存的,如果找不到就取类的名称空间中找,再找不到就要报错了,错误提示:对象没有这个属性
前面我们研究是对象的特征(用变量表示的,接下来我们来研究对象的技能(用函数来表示的),不管是特征还是技能这些都是对象的属性,这是我们前面已经证明过的,那么接下来我们就来调用对象的属性
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self)
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
print(DeepshareStudent.learn)
print(stu1.learn)
print(stu2.learn)
print(id(DeepshareStudent.school))
print(id(stu1.school))
print(id(stu2.school))
我们再来理解一下,类是直接从自己的名称空间中拿到learn属性,而对象在自己的名称空间中找learn属性没有找到,就要到类的名称空间中去找,相当于是间接拿到了learn属性。类内部定义的函数自己能使用,但主要是给对象用的。再来看一下内存地址,上面三个函数属性的内存地址是完全不同的,而下面三个变量属性的内存地址是完全一样的。这是因为类内部的变量是直接给对象使用,而类内部的函数是绑定给对象使用,这怎么理解呢
你们大家都是Deepshare的学生,都有一个相似的技能叫做学习,但是你学习能学到小明身上了,你学习并不能代表小明学习,虽然你们都具有学习的功能。这就叫绑定方法,大家用的是同一个功能,但是绑定给谁,就是谁在执行
那么这在程序中怎么体现呢?
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('is learning')
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
DeepshareStudent.learn('albert')
stu1.learn()
执行代码,我们会发现,类调用learn方法必须要传一个参数,而stu1调用learn方法不需要传参数,但是learn确实是需要一个参数的,那就说明他是自动传了一个参数,我们怎么验证呢?
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('is learning',self) # 打印一下self就知道了
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
DeepshareStudent.learn('albert')
stu1.learn()
print(stu1)
仔细看看是不是一样的
这就说明stu1调用learn方法本质原理就是把它自己传进来
stu1.learn() # DeepshareStudent.learn(stu1)
这就是绑定方法,类内部定义的函数,类可以使用,但是类来使用的时候就是一个普通函数,普通函数有几个参数就传几个参数
print(DeepshareStudent.learn)
DeepshareStudent.learn('albert')
但是类内部定义的函数其实是为了给对象用的,而且是绑定给对象用的,绑定给不同的对象,就是不同的绑定方法
print(stu1.learn)
print(stu2.learn)
绑定方法的特殊之处在于谁来调用,就会把谁当作第一个参数自动传入
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('is learning',self)
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
stu1.learn()
stu2.learn()
接下来我们单独用stu1来说明
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
# self=stu1
def learn(self):
print('%s is learning' % self.name) # self就是stu1,stu1有name方法
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
stu1.learn()
stu2.learn()
综上所述
类内部的变量是给所有对象共享,所有对象指向的都是同一个内存地址; 类内部定义的函数其实是为了给对象用的,而且是绑定给对象用的,绑定给不同的对象,就是不同的绑定方法
类内部定义的函数必须要有self这个参数,但也可以有别的参数
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self.name)
def choose(self,course): # 在添加一个函数
print('%s is choosing %s' %(self.name, course)) # 传一个course参数
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
stu1.choose('Python') # 传一个实参
stu2.choose('AI')
在Python中有一个一切皆对象的说法,面向对象讲到这里我们就可以解释了
class DeepshareStudent:
school = 'deepshare'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print('%s is learning' % self.name)
def choose(self,course):
print('%s is choosing %s' %(self.name, course))
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
stu1 = DeepshareStudent('王二小',18,'male')
stu2 = DeepshareStudent('王三小',18,'male')
print(stu1)
print(type(stu1))
print(id(stu1))
页面更新:2024-03-12
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号