微信公众号:码农充电站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.countryPeople.country 的值都没有被改变。

实际上,这种情况下,类属性的值并没有被改变,而是对象p1 中多了一个country 实例属性,此后,p1.country 访问的是p1 的实例属性,p1.country对属性country的访问屏蔽了类中的country属性,而p2.countryPeople.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 简明教程 --- 15,Python 函数

Python 简明教程 --- 16,Python 高阶函数

Python 简明教程 --- 17,Python 模块与包

Python 简明教程 --- 18,Python 面向对象

Python 简明教程 --- 19,Python 类与对象


欢迎关注作者公众号,获取更多技术干货。

Python 简明教程 --- 20,Python 类中的属性与方法的更多相关文章

  1. python学习-65 继承2-子类中调用父类的方法

    子类中调用父类的方法 1.子类继承了父类的方法,然后想进行修改,那么就需要在子类中调用父类的方法. 2.方法一:父类名 class School: Country = 'china' def __in ...

  2. IDEA如何快速查看类中的属性和方法?

    在idea中,当需要快速的查看一个类的所有属性和方法时,直接去代码中查看,就显得非常的麻烦,idea是有快捷键的,可显示所有的属性和方法,方法如下. 打开一个类,使用快捷键ALT+7,就可以在左侧看到 ...

  3. Python 简明教程 --- 21,Python 继承与多态

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 程序不是年轻的专利,但是,它属于年轻. 目录 我们已经知道封装,继承和多态 是面向对象的三大特征,面 ...

  4. Python 简明教程 --- 22,Python 闭包与装饰器

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 当你选择了一种语言,意味着你还选择了一组技术.一个社区. 目录 本节我们来介绍闭包与装饰器. 闭包与 ...

  5. Python 简明教程 --- 23,Python 异常处理

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 要么做第一个,要么做最好的一个. 目录 我们在编写程序时,总会不自觉的出现一些错误,比如逻辑错误,语 ...

  6. Python 简明教程 --- 24,Python 文件读写

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 过去的代码都是未经测试的代码. 目录 无论是哪种编程语言,IO 操作都是非常重要的部分.I 即Inp ...

  7. Python 简明教程 --- 25,Python 目录操作

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 做技术一定要一颗恒心,这样才不会半途而废. 目录 上一节我们介绍了文件相关的操作,本节我们来介绍目录 ...

  8. python基础教程总结6——类

    1. 如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class  ...

  9. 关于System类中out属性 实例化的问题

    System类中out属性的声明是这样的: public final static PrintStream out = nullPrintStream(); private static PrintS ...

随机推荐

  1. InnoSetup汉化版打包工具下载-附带脚本模板

    InnoSetup汉化版打包工具下载地址: https://www.90pan.com/b1907264 脚本模板 ; 脚本用 Inno Setup 脚本向导 生成.; 查阅文档获取创建 INNO S ...

  2. “造轮运动”之 ORM框架系列(二)~ 说说我心目中的ORM框架

    ORM概念解析 首先梳理一下ORM的概念,ORM的全拼是Object Relation Mapping (对象关系映射),其中Object就是面向对象语言中的对象,本文使用的是c#语言,所以就是.ne ...

  3. Java实现 LeetCode 516 最长回文子序列

    516. 最长回文子序列 给定一个字符串s,找到其中最长的回文子序列.可以假设s的最大长度为1000. 示例 1: 输入: "bbbab" 输出: 4 一个可能的最长回文子序列为 ...

  4. Java实现 LeetCode 217 存在重复元素

    217. 存在重复元素 给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3 ...

  5. Java实现 蓝桥杯VIP 算法提高 超级玛丽

    算法提高 超级玛丽 时间限制:1.0s 内存限制:256.0MB 问题描述 大家都知道"超级玛丽"是一个很善于跳跃的探险家,他的拿手好戏是跳跃,但它一次只能向前跳一步或两步.有一次 ...

  6. Java实现 LeetCode 49 字母异位词分组

    49. 字母异位词分组 给定一个字符串数组,将字母异位词组合在一起.字母异位词指字母相同,但排列不同的字符串. 示例: 输入: ["eat", "tea", & ...

  7. java实现平面4点最小距离

    已知平面上若干个点的坐标. 需要求出在所有的组合中,4个点间平均距离的最小值(四舍五入,保留2位小数). 比如有4个点:a,b,c,d, 则平均距离是指:ab, ac, ad, bc, bd, cd ...

  8. 读懂操作系统之缓存原理(cache)(三)

    前言 本节内容计划是讲解TLB与高速缓存的关系,但是在涉及高速缓的前提是我们必须要了解操作系统缓存原理,所以提前先详细了解下缓存原理,我们依然是采取循序渐进的方式来解答缓存原理,若有叙述不当之处,还请 ...

  9. react后台管理系统路由方案及react-router原理解析

        最近做了一个后台管理系统主体框架是基于React进行开发的,因此系统的路由管理,选用了react-router(4.3.1)插件进行路由页面的管理配置. 实现原理剖析 1.hash的方式   ...

  10. Spyder汉化教程

    汉化包下载地址:https://www.lizenghai.com/archives/523.html 1.解压汉化包 2. 3.1.运行汉化补丁PS C:\WINDOWS\system32> ...