对39讲第0题的疑问,应该是没理解绑定
对于零基础学习Python中第39讲第0题,我写的代码如下class C:
count = 0
def __init__(self):
C.count += 1
def __del__(self):
C.count -= 1
def get_num(self):
print('类实例个数是%d个' % C.count)
然后
c1 = C()
我是这样理解的:代码里面是C.count而不是self.count,其原因是如果用self.count,那么就变成对每个类实例的count属性进行赋值,而不是对C类进行操作。另外不明白为什么用c1.__dict__查看c1,c1为什么没有属性count,但是用c1.count明明又可以输出值? 还有一个就是为什么c1.get_num()是对的,而C.get_num()就说没有参数self,那要怎么样设置参数,才能够使用C.get_num()呢?谢谢 1、c1为什么没有属性count,但是用c1.count明明又可以输出值?
要明白为啥“c1为什么没有属性count,但是用c1.count明明又可以输出值?”,你首先得了解python类的机制:
类实例化后,是没有count这个属性的,但是可以查找到。这就说明实例化类属性没有的,会去上一级定义类中查找。所以count没有dict,但是有输出值。
但是,重点来了:假如你给c1的count赋值了之后,c1的count就会变成实例化类的私有属性,跟定义类中的count所在的栈不同了,这个时候你也就能查到c1中count的dict了。
2、那要怎么样设置参数,才能够使用C.get_num()呢?
不设置self参数,自然就可以调用C.get_num().
但是这就是个静态函数了,你设置在类外也是可以的,不太符合PEP-8的规范,不如将其设置为类方法。
一般情况下,你设置类,就是为了实例化类,所以这个self是必须有的。
本帖最后由 Twilight6 于 2020-7-8 09:11 编辑
先要分清楚类中的各种变量区分:
类体中、所有函数之外:此范围定义的变量,称为类属性或类变量;
类体中,所以函数内部:以“self.变量名”的方式定义的变量,称为实例属性或实例变量;
类体中,所有函数内部:以“变量名=变量值”的方式定义的变量,称为局部变量。然后我们看看问题:
代码里面是C.count而不是self.count,其原因是如果用self.count,那么就变成对每个类实例的count属性进行赋值,而不是对C类进行操作。
count 参数在类内,方法外,属于类变量,而带 self 的变量在方法内属于实例对象,C.count 肯定不是self.count
另外不明白为什么用c1.__dict__查看c1,c1为什么没有属性count,但是用c1.count明明又可以输出值?
类变量是属于类本身的,而 __dict__ 属性是查看对象内部所有属性名和属性值组成的字典
你对 c1 使用属性 __dict__ 是查看这个实例对象所拥有的,所以你看不到 count 属性,你可以 C.__dict__ 来查看类对象所拥有的,就会发现字典中有 'count':'0' 了
还有记住一个对象的属性查找顺序遵循首先查找实例对象自己,然后是类,接着是类的父类。,当你在实例对象自动中找不到count属性,那么他就会去 类中找,类中这里找到了,所以返回了
如果你在类中还是没找到 count 属性,那么他就会去父类找 count 属性,直到找到输出,或者没找到导致报错
还有一个就是为什么c1.get_num()是对的,而C.get_num()就说没有参数self,那要怎么样设置参数,才能够使用C.get_num()呢?
self 实际上就是你的实例对象,而当你对类实例化后的对象调用 get_num() ,这里就会将 c1 这个实例对象自动传入 get_num(self) 中的self,你如果想直接调用类的方法,你可以随便传入一个对象进去,只要是对象都行:
C.get_num(1)
C.get_num('')
C.get_num('asd')
C.get_num([])
楼上说的对~~~
{:9_227:} 本帖最后由 热气球 于 2020-7-8 09:15 编辑
c1.__dict__没有count属性:因为类定义中用的都是类对象的count,而实例化对象自身却没有counut属性。c1.count能输出是因为访问了C.count即类对象的值。
C.get_num()之所以报错是因为没有实例化,只有实例化的实例对象才有self参数。 Twilight6 发表于 2020-7-8 09:02
先要分清楚类中的各种变量区分:
然后我们看看问题:
大佬解释的就是清楚,受教了哈哈 热气球 发表于 2020-7-8 09:17
大佬解释的就是清楚,受教了哈哈
互相学习~ Twilight6 发表于 2020-7-8 09:02
先要分清楚类中的各种变量区分:
然后我们看看问题:
再问一下,如果改成
def get_num():
print('类实例个数是%d个' % C.count)
也就是把self参数去掉,的确C.get_num()可以正确运行,但是c1.get_num()就出错。是不是说如果是像c1这样类实例对象调用get_num时,会把自己作为参数传入。而像C这样的类对象,因为get_num本身就是类方法,而其中没有参数,因此不会传入?谢谢 Tshirt 发表于 2020-7-8 10:38
再问一下,如果改成
def get_num():
print('类实例个数是%d个' % C.count)
对的 实例化后 self 都是把自己传入了,没实例化前因为不知道 self 指的是水导致报错的 Twilight6 发表于 2020-7-8 10:40
对的 实例化后 self 都是把自己传入了,没实例化前因为不知道 self 指的是水导致报错的
感谢感谢
页:
[1]