文章围绕面向对象,讲解了Pyhton的类以及面向对象的三大特性,封装、继承、多态。
这是Python用来初始化类的方法,也称作构造方法。它的参数除了你想要初始化的变量和想要做的操作,还有一个self参数。
在Python类的所有方法的参数列表中,开始的第一个参数一定是self,他是一个指向对象本身的引用,可以通过他来访问类中的变量和方法。self参数无需传值,只需要在定义的时候写在参数列表的第一位即可。
以下是一个示例:
class Student:
def __init__(self, name, number):
self.name = name
self.number = number
def getInfo(self):
print(self.name, self.number)
在变量前加上self,这时形参name的值会存储到变量name中,然后变量name会关联到当前创建的对象。
可以用该函数判断某一对象是否为某个类的实例。
在讲调用之前,我们先来明晰一个概念,就是在类中我们称函数为函数,变量为变量,在实例化后的对象中我们称他的函数为方法,变量为属性。
调用属性的语法是:
对象名.属性名
如果调用得到属性是静态的,也就是类变量还可以这么写:
类名.属性名
这里介绍两个内置函数getattr和hasattr他们的参数列表都是一个对象名和要查询的属性名,分别返回属性的值以及属性是否在对象当中。
讲调用方法前,我们先看下一下的例子
>>> type(Account.deposit)
<class 'Function'>
>>> type(spock_account.deposit)
<class 'method'>
这里的“ Account ”和“ spock_account ”分别是类以及该类的实例对象,他们的函数“ deposit ”的类型分别为函数和方法。产生这种区别的原因主要在于前者是一个双参数函数(假定直接通过对象名调用deposit函数只需要一个参数),而后者是一个单参数函数。前者的参数列表第一个参数是“ self ”(应当是一个对象名),那后者为什么不需要传递参数“ self ”呢?因为在‘ 对象名. “的过程中对象名已经作为” self “参数被传递到了函数里面去。
专用函数是指在类里面以” __ “开头和结尾的函数,他们往往会在某些特殊情况下被Python解释器调用。比如说__init__()函数,他会在这个类实例化为对象的时候自动调用。再者如__len__()函数,当使用Python内置函数len()对某个对象查询长度时,len()函数会调用__len__()函数来获取当前对象的长度,Python的所有序列都实现了__len__()函数。以下是一些常用的专用方法:
方法名 | 方法的返回值或用途 |
---|---|
__init__(self, …) | 类的构造器,用于初始化对象 |
__del__(self) | 类的析构器,用于对象销毁时的清理工作 |
__str__(self) | 返回对象的字符串表示,通常用于打印 |
__repr__(self) | 返回对象的官方字符串表示,通常用于调试 |
__len__(self) | 返回容器类型的长度 |
__getitem__(self, key) | 获取序列的元素,如 obj[key] |
__setitem__(self, key, value) | 设置序列的元素,如 obj[key] = value |
__delitem__(self, key) | 删除序列的元素,如 del obj[key] |
__iter__(self) | 返回对象的迭代器 |
__next__(self) | 返回迭代器的下一个元素 |
__call__(self, …) | 允许一个对象被调用像一个函数 |
__get__(self, instance, owner) | 描述属性的获取方式 |
__set__(self, instance, value) | 描述属性的设置方式 |
__delete__(self, instance) | 描述属性的删除方式 |
__eq__(self, other) | 等于运算符 == 的实现 |
__ne__(self, other) | 不等于运算符 != 的实现 |
__lt__(self, other) | 小于运算符 < 的实现 |
__le__(self, other) | 小于等于运算符 <= 的实现 |
__gt__(self, other) | 大于运算符 > 的实现 |
__ge__(self, other) | 大于等于运算符 >= 的实现 |
__add__(self, other) | 加法运算符 + 的实现 |
__sub__(self, other) | 减法运算符 - 的实现 |
__mul__(self, other) | 乘法运算符 * 的实现 |
__truediv__(self, other) | 除法运算符 / 的实现(Python 3) |
__floordiv__(self, other) | 整除运算符 // 的实现 |
__mod__(self, other) | 模运算符 % 的实现 |
__pow__(self, other[, modulo]) | 幂运算符 ** 的实现 |
__contains__(self, item) | 成员检测运算符 in 的实现 |
__enter__(self) | 上下文管理器协议的进入部分,用于 with 语句 |
__exit__(self, exc_type, exc_val, exc_tb) | 上下文管理器协议的退出部分,用于 with 语句 |
str() 的目的是向调用程序的人输出有关这个类的信息,目的是为了以简洁的语言让人类读懂,是人类友好的;repr() 的目的是输出明确的无歧义的信息,在理想情况下改函数返回的字符串能被eval()解析回原对象,是机器友好的。
除了显式调用 " __str__() " 和 ,在使用print输出一个类的时候,或者使用格式化字符串的时候,或者使用“ + ”拼接对象和字符串的时候都会调用" __str__() "。
print(my_object) # 调用了 my_object.__str__()
formatted_string = "Value: %s" % my_object
formatted_string = "Value: {}".format(my_object)
formatted_string = f"Value: {my_object}"
当向解释器中直接输入对象的名字,则会调用 " __repr__() ",要注意当" __str__() “没有实现的时候,Python解释器会自动调用” __repr__() “,如果连” __repr__() "都没有实现则Python解释器会生成一个默认的字符串表示,这个默认的表示通常是类似于 “ <__main__.ClassName object at memory_address>” 的字符串.
>>> my_object
MyClass(42) # 假设这是 __repr__ 的实现
container = [my_object]
print(container) # 输出可能类似于 [MyClass(42)]
封装即将数据和操作封装到一起,通过控制访问权限,可以将实现细节隐藏对外只表现出接口供外界调用。
Python当中并没有严格限制变量的访问权限,这与其他的面向对象语言有所不同,Python的访问权限表示主要通过变量名或函数名来识别。以‘ _ ’开头的为protected成员,以‘ __ ’开头的是private成员,以‘ __ ’开头结尾的通常是系统定义的特殊成员。
类型 | 权限 |
---|---|
private | 私有成员只有自身的方法能访问 |
protected | 受保护的成员只有自身的方法和子类的方法可以访问 |
default | 默认成员在一个包内的方法可以访问 |
public | 公用成员任何方法都可以访问 |
1)静态变量(类变量):不是在init函数中初始化的变量,而是在类定义中直接声明赋值的变量称作静态变量,他是属于类的,可以通过类名直接调用,所有对象共享。
2)实例方法:普通定义的类方法。
3)类方法(@classmethid):类方法是属于类的方法,可以调用类的类变量,但是不能调用实例变量。用装饰器@classmethid声明。
4)静态方法(@staticmethod):静态方法不访问任何类的属性和方法,用装饰器@staticmethod修饰。
继承需要父类和子类须在同文件中且在子类前面定义。由于子类继承不会调用父类的构造方法,所以需要子类自行调用,定义子类时在类名后面加括号,括号内写父类的名字,子类的init方法先调用父类的init方法再初始化自身的属性。
class parent():
pass
class child(parent):
def __init__(self, ...):
super().__init__(父类初始化的参数列表)
#初始化自身属性
多态指的是子类对象可以传给需要父类类型参数的函数,这时同一个函数表现出什么状态就取决于子类对象的性质。比如Python的运算符重载。
序列
集合与字典
函数
模块和包
异常
文件
类
高级特性