文档章节

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

lionets
 lionets
发布于 2013/10/23 13:20
字数 780
阅读 769
收藏 4
点赞 1
评论 0

可以在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
博文 96
码字总数 131014
作品 0
朝阳
程序员
Python学习笔记二十二(多继承 / 属性和方法 / 常量 / with和上下文管理器 )

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

DragonFangQy ⋅ 05/23 ⋅ 0

python面向对象笔记(what)

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

PowerMichael ⋅ 04/24 ⋅ 0

Python基础-面向对象组合、继承、子类调父类

组合 多个数据属性通过一个类实例化的对象做关联 继承 通过集成可以派生(衍生)出新的方法 单继承 多继承 接口继承 父类规定子类必须要使用的类方法,方便程序归一化设计 接口继承示例 继承顺序...

ZHAO_JH ⋅ 04/13 ⋅ 0

Python面向对象编程之我见

面向对象基本概念 面向对象是一种编程范式。范式是指一组方法论。编程范式是一组如何组织代码的方法论。编程范式指的是软件工程中的一种方法学。 一些主流的编程范式: OOP - 面向对象编程 ...

bigstone2012 ⋅ 05/31 ⋅ 0

day17 继承

1,del()方法 创建对象后,python解释器默认调用init()方法; 当删除一个对象时,python解释器也会默认调用一个方法,这个方法为del()方法 系统自己有这个方法,当执行玩代码后自动删除,如果...

盛夏光年_49e9 ⋅ 2017/11/14 ⋅ 0

Python 类属性与实例属性的关联

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

突然帅了 ⋅ 2015/04/26 ⋅ 1

day17(面向对象基础,类及实例)

del方法 创建对象后,python解释器默认调用init()方法; 当删除一个对象时,python解释器也会默认调用一个方法,这个方法为del()方法 总结: 当有1个变量保存了对象的引用时,此对象的引用计...

冰封心动 ⋅ 2017/11/14 ⋅ 0

Python系列(四)之Python面向对象编程

1. 类和实例 在Python中所有的数据类型都可以视为对象,也可以自定义对象。自定义的对象数据类型即面向对象中的类(Class)概念。类是抽象的模板,实例是具体的对象。 类的定义 Python使用关...

huwh_ ⋅ 2017/12/31 ⋅ 0

能让你代码更 Pythonic 的小技巧

下面例举几个在工作中用到过,个人认为比较 Pythonic 的一些实现个技巧: cached_property 它的作用是将一个方法的计算结果缓存到对象的 当中,熟悉 Flask 的人对这个应该不陌生,Django 应该...

实验楼 ⋅ 06/19 ⋅ 0

Python学习之面向对象高级编程

数据封装、继承和多态只是面向对象程序设计中最基础的3个概念。在Python中,面向对象还有很多高级特性,如:多重继承、定制类、元类等概念。 slots 作用:限制实例的属性。 Python允许在定义...

stone_zhu ⋅ 06/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部