类与对象的其他特性(类属性和对象属性)
6.3 类属性和对象属性
在类定义中 ,属性按照归属分为对象属性 、类属性 。按照调用的私密性分为一般属性和私有属性 。
6.3.1 类属性和对象属性
对象属性是最常用到的一种属性 。即使我们对上面的类:MyClass1实例化了一个mc的对象 ,mc对象也不能进行有实质的操作 。因为mc对象的类:MyClass1中既没有定义属性也没有定义方法 。
在定义类时还能定义类属性 。接下来我们创建一个类:MyClass2 ,并添加一个类属性:class_attr和对象属性:obj_attr 。然后再通过该类实例化一个对象mc 。再通过不同的方式访问类属性和对象属性 ,以便掌握类属性和对象属性的区别 。代码如下: class MyClass2: class_attr = ca def __init__(self): self.obj_attr = oa mc = MyClass2() print(通过对象访问类属性, mc.class_attr) print(通过对象访问对象属性, mc.obj_attr) print(通过类访问类属性, MyClass2.class_attr) print(通过类访问对象属性, MyClass2.obj_attr)通过对象访问类属性 ca
通过对象访问对象属性 oa
通过类访问类属性 ca
Traceback (most recent call last):
File "E:\BaiduNetdiskWorkspace\FrbPythonFiles\study\面向对象\类的私有属性.py", line 12, in
print(通过类访问对象属性, MyClass2.obj_attr)
AttributeError: type object MyClass2 has no attribute obj_attr代码解释:
def __init__(self)::表示创建一个类的构造函数 ,所谓构造函数 ,就是在类的实例化时会自动执行的方法 。在Python类定义时 ,有一些是比较特殊的方法 ,这种方法的方法名一般以双__开始和结尾 ,在Python类中有着特别的意义 。基于此 ,我们一般在类中定义方法时 ,方法名最好不要以__开始 。类一旦进行实例化后 ,就会执行__init__这个构造方法进行初始化,一般这里会进行属性的初始化绑定和一些其他初始化动作。
mc = MyClass2():对MyClass2类的实例化 ,实例化后的对象就是mc 。接下来就可以通过mc来进行操作了 。
self.obj_attr = oa:进行对象属性的值绑定。这里的self代表的就是实例化后的对象自己 。
class_attr = ca:类属性的赋值 ,类属性赋值在类定义后就会生效,不需要实例化成对象 。
通过对象名.属性 、类名.属性就可以获取到相应的属性了 。
通过上面的代码可以看到 ,通过对象是可以正常访问到对象属性的 ,通过类可以访问到类属性 ,但是不能访问到对象属性 。
对象或类对于属性的访问如下: 对象或类 对象属性 类属性 对象 √ √ 类 × √接着我们来看是否能够对属性进行修改:
class Person: age = 18 def __init__(self): self.name = 张三 self.gender = 男 zhangsan = Person() print(通过对象修改对象一般属性, + * 30) print(zhangsan.gender) zhangsan.gender = 女 print(zhangsan.gender) print(通过对象修改类一般属性, + * 30) print(zhangsan.age) zhangsan.age = 30 print(zhangsan.age) print(Person.age) print(通过类修改类一般属性, + * 30) print(Person.age) Person.age = 25 print(Person.age) print(zhangsan.age)通过对象修改对象一般属性 ++++++++++++++++++++++++++++++
男
女
通过对象修改类一般属性 ++++++++++++++++++++++++++++++
18
30
18
通过类修改类一般属性 ++++++++++++++++++++++++++++++
18
25
30通过上面的代码可以看到 ,无论是对象还是类 ,对于能够访问到的属性就可以进行修改 。
但是对象修改类属性后 ,通过类调用的属性不变 。而如果是通过类修改类属性后 ,对象调用的类属性也不变 。也就是说 ,对于类属性 ,对象修改后不会影响到类 ,类修改后也不会影响到对象 。
对象或类对于属性的修改如下: 对象或类 对象属性 类属性 对象 √ √ 类 × √6.3.2 一般属性和私有属性
平常定义类时 ,直接定义的都是一般属性 ,就是可以通过对象名.属性 、类名.属性直接调用到的 。如上面例子中的:mc.class_attr和MyClass2.class_attr 。
如果有些属性名开发者不想让其它开发人员调用时,则可以创建以双__开头的属性名 ,这种属性名称为私有属性 ,在对象 、类进行属性调用时,则不能通过简单的x.属性名的方式调用对象的属性 。 class Person: __age = 18 def __init__(self): self.name = 张三 self.__gender = 男 zhangsan = Person() print(zhangsan.__gender)在上面的定义中 ,通过self.__gender定义了一个私有属性 ,直接运行上面的命令后会报错 ,报错如下:
Traceback (most recent call last):
File "E:\BaiduNetdiskWorkspace\FrbPythonFiles\study\面向对象\创建类.py", line 17, in
print(zhangsan.__gender)
AttributeError: Person object has no attribute __gender当然 ,在Python中没有真正的私有属性 ,通过__开头命名的属性 ,在Python类中只是被自动修改了名称而已 。我们可以通过print(dir(zhangsan))查看到zhangsan这个对象中所有的属性和方法:
[_Person__age, _Person__gender, class, delattr, dict, dir, doc, eq, format, ge, getattribute, gt, hash, init, init_subclass, le, lt, module, ne, new, reduce, reduce_ex, repr, setattr, sizeof, str, subclasshook, weakref]
我们看到 ,输出的结果中有2个属性:_Person__age, _Person__gender ,这个属性其实就是之前定义的__age 和__gender ,因为是私有属性 ,于是Python直接修改了这个属性的名字 ,改成了:_类名+私有属性。于是 ,其实我们可以通过该属性名进行调用:
>>> print(zhangsan._Person__gender)
>>> print(zhangsan._Person__age)
>>> print(Person._Person__age)男
18
18私有属性的修改
class Person: __age = 18 def __init__(self): self.name = 张三 self.__gender = 男 zhangsan = Person() print(通过对象修改对象私有属性, + * 30) print(zhangsan._Person__gender) zhangsan._Person__gender = 女 print(zhangsan._Person__gender) print(通过对象修改类私有属性, + * 30) print(zhangsan._Person__age) zhangsan._Person__age = 30 print(zhangsan._Person__age) print(Person._Person__age) print(通过类修改类私有属性, + * 30) print(Person._Person__age) Person._Person__age = 25 print(Person._Person__age) print(zhangsan._Person__age)通过对象修改对象私有属性 ++++++++++++++++++++++++++++++
男
女
通过对象修改类私有属性 ++++++++++++++++++++++++++++++
18
30
18
通过类修改类私有属性 ++++++++++++++++++++++++++++++
18
25
30我们可以看到,如同一般的属性一样 ,对于类属性 ,对象修改后不会影响到类,类修改后也不会影响到对象 。
注意:按照约定俗成的规定 ,以一个下划线开头的实例变量名(例如_age)在外部是可以直接访问的(弱私有) ,但是这个形式的变量表达的意思是 ,“虽然我可以被访问 ,但是请把我视为私有变量 ,不要随意访问 ” 。一般地在IDE中也会有所提示:保护成员的访问类。6.3.3 类属性和对象属性的区别
现在我们来总结一下类属性和对象属性的区别 。
在定义时 ,使用关键字self来定义对象属性 。而类属性不需要 ,只需要在类最内层直接为变量赋值即可 。该变量就是类属性 。
在访问时 ,可以通过对象.的方式直接访问到一般对象属性和一般类属性 ,而类.的方式只能访问到一般类属性 。对于私有属性无法直接访问 ,但是可以通过x._类名+属性名的方式访问到 。同样的 ,不能通过类.的方式访问到对象的私有属性 。
在修改时 ,可以访问就可以修改,只不过对于类属性 ,对象修改后不会影响到类 ,类修改后也不会影响到对象 。而对象属性,只有对象能够访问和修改 ,类则无法访问 。创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!