微信公众号:码农充电站pro
我的主页:https://codeshellme.github.iohtml
与客户保持良好的关系可使生产率加倍。
—— Larry Bernstainpython
目录git
类中的变量称为属性
,类中的函数称为方法
。github
类中的属性分为:shell
类中的方法分为:微信
self
参数cls
参数,使用@classmethod
装饰器self
参数,也没有cls
参数,使用@staticmethod
装饰器类的对象,就是类的一个实例。类的实例属性
被对象全部,包含在每一个对象之中,不一样的对象之间,互不干扰。类的类属性
被类全部,被包含在类中,是全部的类对象
共享。函数
通常状况下,实例属性会在__init__
方法中声明并初始化,而且使用self
来绑定。而类属性是在类做用域中被声明,而且不使用self
来绑定。code
例以下面代码中,country
为类属性,__name
为实例属性:htm
#! /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
访问的依然是原来的类属性
。
因此,类名.属性名
和对象.属性名
的格式均可以访问类属性
的值,但尽可能避免使用对象.属性名
的格式对类属性的值进行赋值,不然可能会发生混乱。
建议:
无论是访问仍是改变
类属性
的值,都只用类名.属性名
的格式
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
从上面代码中能够看到,在静态方法中不管访问实例方法仍是类方法,都会出现异常。
咱们以前讲到过的魔法方法
,即以双下划线__
开头且结尾的方法__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 类与对象
欢迎关注做者公众号,获取更多技术干货。