文档章节

Python中的类属性和实例属性以及静态方法和类方法

lionets
 lionets
发布于 2013/10/23 13:20
字数 780
阅读 777
收藏 4

可以在Python的类定义中直接添加静态变量,如下例中的foo。此属性属于类C,可以直接通过C.foo访问,而无需实例化它。而实例属性则只存在于对象的实例中,这也就意味着,每一个不同的实例都有只属于自己的实例属性。

class C:
    def __init__(self):
        pass
    foo = 'foo'
c = C()

当我们试图通过一个实例访问某个属性的时候,解释器会首先尝试在实例的命名空间里寻找,如果找不到就会去类属性里找。因此,便会出现下面的情况:

>>> C.foo 
'foo' 
>>> c.foo 
'foo' 
>>> C.foo = 'bar' 
>>> C.foo 
'bar' 
>>> c.foo 
'bar' 
>>> c.foo = 'instance' 
>>> c.foo 
'instance' 
>>> C.foo 
'bar'

当我们实例化C类并将此实例赋值给c时,通过类C和实例c都可以访问到foo属性,实际上这时候访问的是同一个“类属性”(此属性不存在于实例c的命名空间中)。这一点从下面,我们通过类C改变foo的值后,通过实例c访问foo的值也变了,可以看得出来。而当我们试图通过实例c给foo赋值的时候,解释器会把c.foo = 'instance' 这条命令理解为“给实例c的foo属性赋值”,而当他发现实例c没有foo属性的时候,便会自动的给实例c创建一个。这个时候再通过实例c去访问类C的类属性foo就是行不通的了。

通过上面的例子可以看到,类属性的本体是属于类自身的,而实例仅在没有自己的同名实例属性时才可以访问到他。这种特质的一个应用方式就是标记类自身的某些属性,比如版本信息。

P.S.类定义的方法全都是类属性,在实例被创建之前这些方法都不能被调用,因为他们还没有被绑定到特定的实例上。或者也可以简单的理解为,缺少可以传递给类方法的self参数因而调用失败。(arguments 0 given 1 required)除非:使用staticmethod()或classmethod()内建函数将类定义的某个方法“标记(tag),强制类型转换(cast)或者转换(convert)”为静态方法或者类方法。例如如下定义C类:

class C:
   def __init__(self):
       pass

   def foo():
       print("calling static method foo().")
   foo = staticmethod(foo)

   def bar(cls):
       print("calling class method bar().")
       print("bar() is part of class:",cls.__name__)
   bar = classmethod(bar)

当调用foo()和bar()方法时,就不用再实例化C了。注意类方法bar()在定义时传入的默认参数cls,它的作用与self类似(同样只是一个约定俗成的名字cls用于指代类本身):

>>> C.foo() 
calling static method foo(). 
>>> C.bar() 
calling class method bar(). 
bar() is part of class: C

关于Python的类定义方法时为啥必须显式传递一个self参数的问题,这用来表示该方法是否是绑定的,以及绑定在了何处(self / cls)。

© 著作权归作者所有

共有 人打赏支持
lionets
粉丝 90
博文 98
码字总数 132850
作品 0
朝阳
程序员
Python3 与 C# 面向对象之~封装

最新彩版:https://www.cnblogs.com/dotnetcrazy/p/9202988.html 在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode/master 在线预览:http://github.lesschina.com/python/base/oop/1......

毒逆天
06/20
0
0
Python学习笔记二十二(多继承 / 属性和方法 / 常量 / with和上下文管理器 )

多继承 狮虎兽, 不知道你有没有听说过? 狮虎兽,是雄狮(Panthera leo)与雌虎(Panthera tigris)杂交后的产物,是属于猫科豹属的一员. 用程序模拟一下狮虎兽. 当子类有多个父类 ( Lion 和 ...

DragonFangQy
05/23
0
0
Python 类属性与实例属性的关联

类属性是属于一个类的变量,就像是C++中类的静态成员变量,你只需将该属性定义在所有方法的作用域外,即为类属性,但一般是紧跟在类名后面,类属性为所有实例所共有,你可以通过 类名.属性 ...

突然帅了
2015/04/26
0
1
Python基础班每日整理(六)

03面向对象day03 类属性和实例属性的概念。 类属性是给类对象(类是一个特殊的对象)中定义的属性,通常用来记录与这个类相关的特征,类属性不会用于记录具体对象的特征。类属性的定义是在初始...

我是小谷粒
07/02
0
0
python面向对象笔记(what)

python面向对象笔记(what) 1.什么是面向对象? 对象相当于把函数和全局变量封装起来,属相相当于全局变量,方法相当于函数。 不同对象相互隔离,全局变量互不影响。 2.什么是隐藏属性? 在方...

PowerMichael
04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

angular 解决其他电脑不能访问的问题。

ng serve --host 0.0.0.0 --disable-host-check

miaojiangmin
今天
1
0
优酷视频文件怎么转换格式

  以前在优酷上下载视频都只是在手机上观看,但随着科技的发展,对于视频的要求也逐渐增多,不再只是观看视频那么简单,在精彩的部分还会将其单独分割出来,然后进行视频剪辑,可以做出我们...

萤火的萤火
今天
0
0
数据结构:散列

在一个数据结构中查找key元素,用顺序查找、二分查找都需要经过一系列关键之比较才能查找到结果,平均查找长度与数据量有关,元素越多比较次数就越多。 如果根据元素的关键字就能知道元素的存...

京一
今天
0
0
Apache RocketMQ 正式开源分布式事务消息

近日,Apache RocketMQ 社区正式发布4.3版本。此次发布不仅包括提升性能,减少内存使用等原有特性增强,还修复了部分社区提出的若干问题,更重要的是该版本开源了社区最为关心的分布式事务消...

阿里云云栖社区
今天
30
0
使用JavaScript和MQTT开发物联网应用

如果说Java和C#哪个是最好的开发语言,无疑会挑起程序员之间的相互怒怼,那如果说JavaScript是动态性最好的语言,相信大家都不会有太大的争议。随着越来越多的硬件平台和开发板开始支持JavaS...

少年不搬砖老大徒伤悲
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部