'''
作者:韭白
源自:
https://www.cnblogs.com/shockerli/p/python-study-note.html
'''
面向对象
类与对象是面向对象编程的两个主要方面。一个
类
(Class)能够创建一种新的类型(Type),其中
对象
(Object)就是类的
实例
(Instance)。可以这样来类比:你可以拥有类型
int
的变量,也就是说存储整数的变量是
int
类的实例(对象)。
-
类(Class)
:用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
-
方法
:类中定义的函数。
-
类变量
:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
-
数据成员
:类变量或者实例变量用于处理类及其实例对象的相关的数据。
-
方法重写
:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
-
实例变量
:定义在方法中的变量,只作用于当前实例的类。
-
继承
:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
-
实例化
:创建一个类的实例,类的具体对象。
-
对象
:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
Python 中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
对象可以包含任意数量和类型的数据。
self
self
表示的是当前实例,代表当前对象的地址。类由
self.__class__
表示。
self
不是关键字,其他名称也可以替代,但
self
是个通用的标准名称。
类
类由
class
关键字来创建。
类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。
对象方法
方法由
def
关键字定义,与函数不同的是,方法必须包含参数
self
, 且为第一个参数,
self
代表的是本类的实例。
类方法
装饰器
@classmethod
可以将方法标识为类方法。类方法的第一个参数必须为
cls
,而不再是
self
。
静态方法
装饰器
@staticmethod
可以将方法标识为静态方法。静态方法的第一个参数不再指定,也就不需要
self
或
cls
。
__init__ 方法
__init__
方法即构造方法,会在类的对象被实例化时先运行,可以将初始化的操作放置到该方法中。
如果重写了
__init__
,实例化子类就不会调用父类已经定义的
__init__
。
变量
类变量
(Class Variable)是共享的(Shared)——它们可以被属于该类的所有实例访问。该类变量只拥有一个副本,当任何一个对象对类变量作出改变时,发生的变动将在其它所有实例中都会得到体现。
对象变量
(Object variable)由类的每一个独立的对象或实例所拥有。在这种情况下,每个对象都拥有属于它自己的字段的副本,也就是说,它们不会被共享,也不会以任何方式与其它不同实例中的相同名称的字段产生关联。
在 Python 中,变量名类似
__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是 private 变量,所以,不能用
__name__
、
__score__
这样的变量名。
访问控制
我们还认为约定,一个下划线开头的属性或方法为
受保护
的。比如,
_protected_attr
、
_protected_method
。
继承
类可以继承,并且支持继承多个父类。在定义类时,类名后的括号中指定要继承的父类,多个父类之间用逗号分隔。
子类的实例可以完全访问所继承所有父类的非私有属性和方法。
若是父类中有相同的方法名,而在子类使用时未指定,Python 从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法。
方法重写
子类的方法可以重写父类的方法。重写的方法参数不强制要求保持一致,不过合理的设计都应该保持一致。
super()
函数可以调用父类的一个方法,以多继承问题。
类的专有方法:
-
__init__
: 构造函数,在生成对象时调用
-
__del__
: 析构函数,释放对象时使用
-
__repr__
: 打印,转换
-
__setitem__
: 按照索引赋值
-
__getitem__
: 按照索引获取值
-
__len__
: 获得长度
-
__cmp__
: 比较运算
-
__call__
: 函数调用
-
__add__
: 加运算
-
__sub__
: 减运算
-
__mul__
: 乘运算
-
__div__
: 除运算
-
__mod__
: 求余运算
-
__pow__
: 乘方
类的专有方法也支持重载。
实例
class Person:
"""人员信息"""
name = ''
age = 0
def __init__(self, name='', age=0):
self.name = name
self.age = age
def __str__(self):
return "这里重载了 __str__ 专有方法, " + str({'name': self.name, 'age': self.age})
def set_age(self, age):
self.age = age
class Account:
"""账户信息"""
__balance = 0
__total_balance = 0
def balance(self):
return self.__balance
def balance_add(self, cost):
self.__balance += cost
self.__class__.__total_balance += cost
@classmethod
def total_balance(cls):
return cls.__total_balance
@staticmethod
def exchange(a, b):
return b, a
class Teacher(Person, Account):
"""教师"""
_class_name = ''
def __init__(self, name):
super(Teacher, self).__init__(name)
def get_info(self):
return {
'name': self.name,
'age': self.age,
'class_name': self._class_name,
'balance': self.balance(),
}
def balance(self):
return Account.balance(self) * 1.1
class Student(Person, Account):
"""学生"""
_teacher_name = ''
def __init__(self, name, age=18):