前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开源图书《Python完全自学教程》8.3.1类属性

开源图书《Python完全自学教程》8.3.1类属性

作者头像
老齐
发布2022-07-06 16:10:46
3600
发布2022-07-06 16:10:46
举报
文章被收录于专栏:老齐教室老齐教室

8.3 属性

Python 语言中对象的属性,可以分为类属性(Class Attribute)和实例属性(Instance Attribute)。在8.2节所演示的初始化方法中定义的属性,都属于实例属性。本节要对类属性和实例属性分别进行深入阐述。

8.3.1 类属性

在交互模式下,创建一个简单的类。

代码语言:javascript
复制
>>> class Foo:
...     lang = 'python'       # (1)
...     def __init__(self, name):
...         self.name = name
...

这里定义的类 Foo 中有一个独立于方法之外的赋值语句(注释(1)所示),这个赋值语句中的变量 lang 称为类 Foo 的类属性。顾名思义,“类属性”就是“从属于类的属性”,可以通过类名称访问。

代码语言:javascript
复制
>>> Foo.lang
'python'

从本质上看,注释(1)就是赋值语句,因此可以理解为 Foo.lang 这个变量引用了字符串对象 'python'

不妨将“类属性”类比于产品的标准配置——每个产品在生产出来之后都具有的特性。在创建实例的时候,类属性会自动配置到每个实例中,即:通过实例也可以访问该属性——但它不是从属于实例的属性,切记!。

代码语言:javascript
复制
# 第一个实例
>>> j = Foo('java')
>>> j.lang
'python'
# 第二个实例
>>> r = Foo('ruby')
>>> r.lang
'python'

而在初始化方法 __init__() 中所创建的 self.name 属性,则会因为实例化时提供不同的实参,其值不相同,即这个属性会随实例而改变,故称之为实例属性——从属于实例的属性。

代码语言:javascript
复制
>>> j.name
'java'
>>> r.name
'ruby'

name 属性不能用类名称访问:

代码语言:javascript
复制
>>> Foo.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute 'name'

类属性可以通过类名称访问,也可以通过类名称进行修改,如:

代码语言:javascript
复制
>>> Foo.lang = 'pascal'    # (2)
>>> Foo.lang
'pascal'

注释(2)是一个赋值语句——参考注释(1),所谓“修改”,本质上变量 Foo.lang 引用了另外一个对象。

通过类名称(或者说类对象)修改了类属性的值,如果再用实例访问这个属性,发现其值也已经改变。

代码语言:javascript
复制
>>> j.lang
'pascal'
>>> r.lang
'pascal'

这再次说明,属性 lang 不是在实例化的时候创建的,而是随着类的创建存在的。

还可以通过类名称增加类属性。

代码语言:javascript
复制
>>> Foo.author = 'laoqi'
>>> hasattr(Foo, 'author')    # 判断对象 Foo 是否有属性 author
True
>>> Foo.author
'laoqi'
>>> j.author
'laoqi'
>>> r.author
'laoqi'

如果删除类属性,可以使用 del 语句(参阅第6章6.1.3节)。

代码语言:javascript
复制
>>> del Foo.author
>>> hasattr(Foo, 'author')
False

Foo.author 属性已经删除,不论是类名称还是实例名称,都不能访问到此属性。

代码语言:javascript
复制
>>> j.author
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'author'

在 Python 中,不论什么对象,其属性都在该对象的 __dict__ 属性中—— __dict__ 名称是双下划线开始和结束。

代码语言:javascript
复制
>>> Foo.__dict__
mappingproxy({'__module__': '__main__', 'lang': 'pascal', '__init__': <function Foo.__init__ at 0x7ff5cae445e0>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None})

在返回结果中,以类字典的方式列出了对象 Foo 的所有属性——类属性, 'lang': 'pascal' 也在其中。而如果访问实例的 __dict__ 属性,所得结果有所不同。

代码语言:javascript
复制
>>> j.__dict__
{'name': 'java'}

这里只有在实例化时创建的属性——实例属性,下面就重点研习它。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 8.3 属性
    • 8.3.1 类属性
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档