Python 简明教程 --- 20,Python 类中的属性与方法
source link: https://codeshellme.github.io/2020/06/python-learn20/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
微信公众号:码农充电站pro
与客户保持良好的关系可以使生产率加倍。
—— 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__
方法
实现该方法的类的对象,可以进行小于等于<=
比较。
推荐阅读:
欢迎关注作者公众号,获取更多技术干货。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK