Python 简明教程 --- 20,Python 类中的属性与方法
微信公众号:码农充电站pro
个人主页:https://codeshellme.github.io
与客户保持良好的关系可以使生产率加倍。
—— Larry Bernstain
目录
类中的变量称为属性
,类中的函数称为方法
。
类中的属性分为:
- 实例属性:对象所有,互不干扰
- 类属性:类所有,所有对象共享
类中的方法分为:
- 实例方法:定义中有
self
参数 - 类方法:定义中有
cls
参数,使用@classmethod
装饰器 - 静态方法:定义中即没有
self
参数,也没有cls
参数,使用@staticmethod
装饰器
1,实例属性与类属性
类的对象,就是类的一个实例。类的实例属性
被对象所有,包含在每个对象之中,不同的对象之间,互不干扰。类的类属性
被类所有,被包含在类中,是所有的类对象
共享。
一般情况下,实例属性会在__init__
方法中声明并初始化,并且使用self
来绑定。而类属性是在类作用域中被声明,并且不使用self
来绑定。
例如下面代码中,country
为类属性,__name
为实例属性:
#! /usr/bin/env python3
class People:
country = 'china'
def __init__(self, name):
self.__name = name
访问实例属性时使用对象.属性名
的格式,实例属性属于对象各自的,互不影响:
>>> p1 = People('小明')
>>> p2 = People('小美')
>>>
>>> p1.get_name()
'小明'
>>> p2.get_name()
'小美'
类属性被所有对象共有,一旦被改变,所有对象获取到的值都会被改变。访问类属性时使用类名.属性名
的格式,也可以使用对象.属性名
的格式来访问:
>>> People.country # 用`类名.属性名`的格式访问
'CHINA'
>>> p1.country # 用`对象.属性名`的格式访问
'china'
>>> p2.country
'china'
>>>
>>> People.country = 'CHINA' # 类属性的值被改变
>>> p1.country # 每个对象获取到的值也会被改变
'CHINA'
>>> p2.country
'CHINA'
注意,在使用对象.属性名
的格式访问对象时,不要以这种格式对类属性
进行赋值,否则结果可能不会像你想象的一样:
>>> p1 = People('小明')
>>> p2 = People('小美')
>>> People.country
'china'
>>> p1.country
'china'
>>> p2.country
'china'
>>> p1.country = '中国' # 使用`对象.属性名`的格式对类对象进行赋值
>>> p1.country # 只有 p1.country 被改变
'中国'
>>> p2.country # p2.country 没有被改变
'china'
>>> People.country # People.country 也没有被改变
'china'
从上面代码中可以看到,在Python 中以对象.属性名
格式对类属性
进行赋值时,只有p1.country
的值被改变了,p2.country
和 People.country
的值都没有被改变。
实际上,这种情况下,类属性
的值并没有被改变,而是对象p1
中多了一个country
实例属性,此后,p1.country
访问的是p1
的实例属性,p1.country
对属性country
的访问屏蔽了类中的country
属性,而p2.country
和 People.country
访问的依然是原来的类属性
。
所以,类名.属性名
和对象.属性名
的格式都可以访问类属性
的值,但尽量避免使用对象.属性名
的格式对类属性的值进行赋值,否则可能会发生混乱。
建议:
不管是访问还是改变
类属性
的值,都只用类名.属性名
的格式
2,实例方法,类方法,静态方法
Python 类中有三种方法:
- 实例方法
- 类方法
- 静态方法
实例方法
属于对象,方法中都有一个self
参数(代表对象本身)。实例方法只能由对象调用,不能通过类名访问。实例方法中可以访问实例属性和类属性。
类方法
属于类,方法中都有一个cls
参数(代表类本身)。类方法即可以通过类名访问,也可以通过对象访问,类方法中只能访问类属性,不能访问实例属性。
注意:
Python 解释器在构造类与对象时,
类
是先于对象
产生的。因此,
类属性与类方法
是先于实例属性与实例方法
产生的。所以当类方法产生时,还没有实例属性,因此,类方法中不能访问实例属性。
静态方法
中,没有self
参数,也没有cls
参数。因此,在静态方法中,即不能访问类属性
,也不能访问实例属性
。静态方法可以使用类名访问,也可以使用对象访问。
在Python 中,定义类方法需要用到装饰器@classmethod
,定义静态方法需要用到装饰器@staticmethod
。
实例方法演示
#! /usr/bin/env python3
class People:
country = 'china'
def __init__(self, name):
self.__name = name
# 实例方法中有self 参数
def instance_method_test(self):
# 在实例方法中访问了实例属性和类属性
print('name:%s country:%s' % (self.__name, People.country))
使用:
>>> p = People('小明')
>>> p.instance_method_test()
name:小明 country:china
在实例方法中访问了实例属性__name
和类属性country
,均可以被访问。
类方法演示
#! /usr/bin/env python3
class People:
country = 'china'
def __init__(self, name):
self.__name = name
# 类方法中都有cls 参数
@classmethod
def class_method_test1(cls):
print('在类方法中访问类属性country:%s' % cls.country)
@classmethod
def class_method_test2(cls):
print('在类方法中访问实例属性__name:%s' % self.__name)
使用:
>>> p = People('小明')
>>> p.class_method_test1() # 在类方法中访问类属性,可以
在类方法中访问类属性country:china
>>>
>>> p.class_method_test2() # 在类方法中访问实例属性,出现异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/wp/to_beijing/People.py", line 18, in class_method_test2
print('在类方法中访问实例属性__name:%s' % self.__name)
NameError: name 'self' is not defined
从上面代码中可以看到,在类方法中可以访问类属性,但在类方法中访问实例属性,会出现异常。
静态方法演示
#! /usr/bin/env python3
class People:
country = 'china'
def __init__(self, name):
self.__name = name
# 静态方法中即没有self 参数也不没有cls 参数
@staticmethod
def static_method_test1():
print('在静态方法中访问类属性country:%s' % cls.country)
@staticmethod
def static_method_test2():
print('在静态方法中访问实例属性__name:%s' % self.__name)
使用:
>>> p = People('小明')
>>> p.static_method_test1() # 在静态方法中访问类属性,出现异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/wp/to_beijing/People.py", line 14, in static_method_test1
print('在静态方法中访问类属性country:%s' % cls.country)
NameError: name 'cls' is not defined
>>>
>>> p.static_method_test2() # 在静态方法中访问实例属性,出现异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/wp/to_beijing/People.py", line 18, in static_method_test2
print('在静态方法中访问实例属性__name:%s' % self.__name)
NameError: name 'self' is not defined
从上面代码中可以看到,在静态方法中无论访问实例方法还是类方法,都会出现异常。
3,专有方法
我们之前讲到过的魔法方法
,即以双下划线__
开头且结尾的方法__xxx__
,就是专有方法
。这些方法都被Python 赋予了特殊的含义,用户可以根据需要,来实现这些方法。
下面我们介绍一些 Python 中常见的专有方法。
__len__
方法
实现该方法的类的对象,可以用len()
函数计算其长度。
__str__
方法
实现该方法的类的对象,可以转化为字符串。
__call__
方法
实现该方法的类的对象,可以像函数一样调用。
__iter__
方法
实现该方法的类的对象,是可迭代的。
__setitem__
方法
实现该方法的类的对象,可以用索引
的方式进行赋值。
__getitem__
方法
实现该方法的类的对象,可以用索引
的方式进行访问。
__contains__
方法
实现该方法的类的对象,可以进行in
运算。
__add__
方法
实现该方法的类的对象,可以进行加+
运算。
__sub__
方法
实现该方法的类的对象,可以进行减-
运算。
__mul__
方法
实现该方法的类的对象,可以进行乘*
运算。
__div__
方法
实现该方法的类的对象,可以进行除/
运算。
__pow__
方法
实现该方法的类的对象,可以进行乘方
运算。
__mod__
方法
实现该方法的类的对象,可以进行取模
运算。
__eq__
方法
实现该方法的类的对象,可以进行相等==
比较。
__ne__
方法
实现该方法的类的对象,可以进行不等于!=
比较。
__gt__
方法
实现该方法的类的对象,可以进行大于>
比较。
__ge__
方法
实现该方法的类的对象,可以进行大于等于>=
比较。
__lt__
方法
实现该方法的类的对象,可以进行小于<
比较。
__le__
方法
实现该方法的类的对象,可以进行小于等于<=
比较。
(完。)
推荐阅读:
Python 简明教程 --- 16,Python 高阶函数
Python 简明教程 --- 17,Python 模块与包
Python 简明教程 --- 18,Python 面向对象
Python 简明教程 --- 19,Python 类与对象
欢迎关注作者公众号,获取更多技术干货。
Python 简明教程 --- 20,Python 类中的属性与方法的更多相关文章
- python学习-65 继承2-子类中调用父类的方法
子类中调用父类的方法 1.子类继承了父类的方法,然后想进行修改,那么就需要在子类中调用父类的方法. 2.方法一:父类名 class School: Country = 'china' def __in ...
- IDEA如何快速查看类中的属性和方法?
在idea中,当需要快速的查看一个类的所有属性和方法时,直接去代码中查看,就显得非常的麻烦,idea是有快捷键的,可显示所有的属性和方法,方法如下. 打开一个类,使用快捷键ALT+7,就可以在左侧看到 ...
- Python 简明教程 --- 21,Python 继承与多态
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 程序不是年轻的专利,但是,它属于年轻. 目录 我们已经知道封装,继承和多态 是面向对象的三大特征,面 ...
- Python 简明教程 --- 22,Python 闭包与装饰器
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...
- Python 简明教程 --- 23,Python 异常处理
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 要么做第一个,要么做最好的一个. 目录 我们在编写程序时,总会不自觉的出现一些错误,比如逻辑错误,语 ...
- Python 简明教程 --- 24,Python 文件读写
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 过去的代码都是未经测试的代码. 目录 无论是哪种编程语言,IO 操作都是非常重要的部分.I 即Inp ...
- Python 简明教程 --- 25,Python 目录操作
微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 做技术一定要一颗恒心,这样才不会半途而废. 目录 上一节我们介绍了文件相关的操作,本节我们来介绍目录 ...
- python基础教程总结6——类
1. 如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class ...
- 关于System类中out属性 实例化的问题
System类中out属性的声明是这样的: public final static PrintStream out = nullPrintStream(); private static PrintS ...
随机推荐
- Rocket - util - Misc
https://mp.weixin.qq.com/s/kf4FvAFye_bRdT49Yow7Hg 简单介绍Misc中各个辅助方法的用途和实现. 1. ParameterizedBu ...
- (Java实现) 洛谷 P1098 字符串的展开
import java.util.ArrayList; import java.util.Scanner; public class zifuchuandezhankai { static Array ...
- Java实现 LeetCode 706 设计哈希映射(数组+链表)
706. 设计哈希映射 不使用任何内建的哈希表库设计一个哈希映射 具体地说,你的设计应该包含以下的功能 put(key, value):向哈希映射中插入(键,值)的数值对.如果键对应的值已经存在,更新 ...
- Java实现 LeetCode 432 全 O(1) 的数据结构
432. 全 O(1) 的数据结构 实现一个数据结构支持以下操作: Inc(key) - 插入一个新的值为 1 的 key.或者使一个存在的 key 增加一,保证 key 不为空字符串. Dec(ke ...
- java实现第七届蓝桥杯取球博弈
题目9.取球博弈 取球博弈 两个人玩取球的游戏. 一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目. 如果无法继续取球,则游戏结束. 此时,持有奇数个球的一方获胜. 如果两 ...
- Java实现第八届蓝桥杯9算数式
9算数式 题目描述 观察如下的算式: 9213 x 85674 = 789314562 左边的乘数和被乘数正好用到了1~9的所有数字,每个1次. 而乘积恰好也是用到了1~9的所有数字,并且每个1次. ...
- jstat监控JVM内存使用、GC回收情况
jstat -gcutil 2388 3000 6 每隔3秒打印一次pid为2388的堆内存的使用情况,共打印6次 S0— Heap上的 Survivor space 0 区已使用空间的百分比 S1 ...
- C#基础篇——委托
前言 在本章中,主要是借机这个C#基础篇的系列整理过去的学习笔记.归纳总结并更加理解透彻. 在.Net开发中,我们经常会遇到并使用过委托,如果能灵活的掌握并加以使用会使你在编程中游刃有余,然后对于很多 ...
- vue甘特图gantt
vue做甘特图,先大致介绍下核心功能: (1)横轴.纵轴拖拽: (2)自定义监听点击事件(双击.右键等)(3)任务之间显示父子层级关系:(4)左侧列表信息,右侧时间轴表示任务:(5)每个任务可以订制样 ...
- OpenSSL & 加密解密
OpenSSL&加密解密(思维导图) 1. 网络通信概述 传输层协议 进程间通信 监听端口 SSL 裸套接字 2. 加密和解密 2.1 加密的方式 对称加密 公钥加密 单向加密 认证加密 2. ...