class MyObject(object): x = 1 def __init__(self): objectNum = 99 def changeNum(self,anotherNum): self.objectNum = anotherNum showNum(self): print("self.num = ",self.objectNum)
什么问题呢,看似构造函数__init__中的变量object在实例化对象的时候会自动创建并初始化为99,其实不然,这里用一个小的测试代码就可以发现问题。obj = MyObject()obj.showNum()Traceback (most recent call last): file class.pyin <module> obj.showNum() file in showNum ",self.objectNum)AttributeError: 'MyObject' object has no attribute objectNum'
报错了,提示实例化对象MyObject并没有objectNum这个普通成员变量,为什么呢?问题就在于,在Python中,类的成员变量必须使用self.propertname进行声明,这样才能完成创建,因为self的含义就是代表实例对象;在这个类中,objectNum和self.objectNum就是两个完全不同的东西:定义在__init__函数中的变量objectNum在这里是一个局部变量,不是类变量 接下来我们可以再写一段代码,调用changNum()方法,来生成这个成员变量self.objectNum:obj = MyObject()obj.changeNum(10)obj.showNum()>>> self.num = 10
能看到成功返回结果,由于在changeNum()方法中,有self.objectNum = anotherNum的赋值,而__init__中,没有创建类普通成员变量self.objectNum, 而是创建了一个临时变量objectNum,所以在这里,虽然changeNum()没有被自动调用(因为不是__init__()函数),但是其实充当了创建类成员变量和初始化的作用, 但是python并不会在创建新的实例化对象的时候自动调用它。 所以通过实验得到3个结论:1.python中的"构造函数"非常的自由,如果不考虑自动调用,任何类方法都可以去创建类成员变量: ExampleClass: createObjectProperty(self,value):self.newObjectProperty = value
如上面的代码,这里声明一个类方法,传入参数self 和 value,调用这个方法,就可以生成一个普通成员变量newObjectProperty,并对其赋初值value2.如果想要找到真正意义上的成员变量,那么只需要在__init__(self)中声明self.objectProperty即可3.python中的self不能隐式调用,如果你不想生成一个临时变量而是创建一个类成员变量,那么就应该使用self.variablename(self): self.objectNum = 99 obj = MyObject()# obj.changeNum(10)obj.showNum()>>>self.num = 99知道了成员变量的问题之后,再来讨论一下类变量MyObject() print(MyObject.x)>>> 1
在声明类T的时候,我们在所有的方法之外(但是仍在类的作用域中声明了一个变量classNum),从命名的角度来看,我们希望这是一个类变量,但我们不希望这次又是一个成员变量,测试发现它确实可以由类名直接访问再试一下能否修改:
MyObject.x = 100(MyObject.x)>>> 100
发现可以修改下面我们验证一下其是否能被所有实例化对象访问和修改,并且是否具有全局性。t1 = MyObject()(t1.x)>>> 1t2 =(t2.x)>>> 1MyObject.x = 1000(t1.x)>>> 1000(t2.x)>>> 1000t1.x = 2000(t2.x)>>>1000(t1.x)>>>2000(MyObject.x)>>>1000
从以上结果看出类名.类变量名修改其值会导致实例化对象的值全部被改变,但是用实例化对象名.类变量名修改其值,就仅仅改变自己,不会真的改变类变量的数值。我们来检查一下内存,看一段代码:t2 = MyObject()t1 =print(MyObject.x is t1.x)>>>True t2.x)>>>print(t2.x True--------------------------------------- MyObject() t2.x = 10FalseFalse-------------------------------------- MyObject() MyObject.x = 100t2.x = 10 t1.x)>>>False
看得出来在最开始的时候MyObject.x和实例化对象t1.x与t2.x内存是同一处的,但当直接修改了实例化对象t2.x的数值后t2.x内存的数值便与其他两个不同,所以直接修改实例化对象的数值会指向新的内存空间,并且不受类变量改变而改变。总结:一个类=类变量(可以没有)+构造函数(必须有,没有的话默认调用)成员函数(自己定义,可以没有)构造函数中定义了类的成员变量,类的成员变量一定是在构造函数中以self.开头的变量!
成员函数中可以调用成员变量和类变量!成员函数的形参在类的实例调用该函数时传递,成员函数的局部变量在该成员函数内部定义。调用成员函数和调用普通函数一样,只是成员函数由该函数对应的类调用,即需要写成xxxx.func()而不是直接使用func()!
总结以上是内存溢出为你收集整理的python类变量与__init__声明变量的区别全部内容,希望文章能够帮你解决python类变量与__init__声明变量的区别所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)