类
对属性和方法的封装
对象是类的实例
面向对象:Object Oriented(OO)
方法:
实例对象名.__dict__#返回该实例创建的属性的字典
可以直接使用self.__dict__[] = value创建属性
类:
class 类名(父类):
#属性
color = 'green'
#方法
def climb(self)
……
可以在类定义之外添加属性(类成员)
c.x = 1#直接定义、赋值即可
对象:
变量名 = 类名()
方法:
self:相当于this指针
对象名.()
#如果方法和属性同名,方法将无法使用
#类中两个方法代码完全相同可以直接赋值...aaa = bbb
#函数名直接赋值就可以换一个名字...self.aaa = t.bbb
封装
继承
class 类名称(父类)
class 类名称(父类1, 父类2, ……)#多重继承
1. 先调用父类__init__()函数,再调用子类__init__()函数方法
类名.__mro__()#查看查找类中方法的顺序(MRO顺序)
(1). 调用未绑定的父类方法
Fish.__init__(self)#直接调用即可,self是子类的指针
(2). 使用super函数:改变基类无需修改代码,super只会调用一次,不会出现调用多次的钻石继承/菱形继承(多重继承的问题)
super().__init__()#直接调用即可,无需传递self参数
多态(鸭子类型):类似C++中的父类指针可以指向子类对象
class Duck:
def quack(self):
print("呱呱呱!")
def feathers(self):
print("这个鸭子拥有灰白灰白的羽毛。")
class Person:
def quack(self):
print("你才是鸭子你们全家人是鸭子!")
def feathers(self):
print("这个人穿着一件鸭绒大衣。")
def in_the_forest(duck):
duck.quack()
duck.feathers()
def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)#in_the_forest()函数可以接受任何具有quack()和feathers()函数的类对象作为参数
game()
类的专有方法:
构造函数:
__init__(self, param1, param2, ……)#相当于构造函数
class Ball:
def __init__(self, name)#必须返回None
self.name = name
析构函数:
__del__(self, ……)#相当于析构函数,没有任何变量指向该对象时自动调用
__str__()#改变print()的显示
__repr__()#改变对象直接的显示
__setitem__()#按照索引赋值
__getitem__()#按照索引获取值
__len__()#获取长度
__cmp__()#比较运算
__call__()#函数调用
__add__()#加运算
__sub__()#减运算
__mul__()#乘运算
__turediv__()#除运算
__mod__()#求余运算
__pow__()#乘方
__new__(cls[, ……])#在__init__()之前调用,必须返回一个类对象,通常是cls的类对象,必须返回一个对象(返回的对象就是self)
__getattr__(self, name)#定义当用户获取不存在属性时的行为
__getattribute__(self, name)#定义当该类属性被访问时的行为,无论存在与否,先访问该方法
__setattr__(self, name, value)#定义当一个属性被设置时的行为
#在该方法中设置属性时,会触发该函数,无限递归,此时应该调用基类的方法super().__setattr__(name, value)
#变量刚刚定义时一定会调用该方法
__delattr__(self, name)#定义当一个属性被删除的行为
__dict__()#将类中的属性通过字典显示出来,也可以通过该方法返回的字典修改对象中的属性值,不会触发其他方法
私有变量:(伪私有)
函数名/变量名前加__
访问:_类名_属性名
类之间的关系:
组合:类中包含另一个类的对象
Mix-in
类、类对象、实例对象:
类:类的定义
在类的定义中的属性是静态变量
类对象:类名也是一个对象
类名.__dict__#返回与该类对象绑定的字典:键,属性名/值:属性值,方法绑定在类对象上,方法是静态的(static),不会因为类对象被del而无法使用
#类对象修改属性后,其他未改变该属性的实例对象会一起修改
#使用类对象定义的属性是静态变量
实例对象:除了类名之外的其他对象其他对象,修改实例对象属性会覆盖类对象属性
实例对象名.__dict__#返回该实例创建的属性的字典
#使用实例对象定义的属性是实例属性
绑定:
概念:普通的方法(静态的:相当于static)需要有实例(self)才能调用,这就是一种绑定
相关的BIF:
issubclass(class, classinfo)#第一个参数是否是第二个参数的子类True/False:(自己是自己的子类,classinfo可以是类对象组成的元组/只要class与任何一个元素是继承关系/返回True,所有的类都是被认为继承于object),TypeError:()
isinstance(object, classinfo)#检查实例对象是否属于一个类, True/False:(第一个参数不是对象时返回False), TypeError:(第二个参数不是类或类的元组时)
hasattr(object, name)#判断一个对象是否有一个属性(name是字符串)
getattr(boject, name[, default])#返回对象指定的属性值,如果属性不存在,则打印可选参数default,未设置default且不存在该属性时抛出AttributeError
setattr(object, name, value)#设置对象中属性的值,如果属性不存在,则为对象创建属性
delattr(object, name)#删除对象中指定的属性,如果属性不存在,则抛出AttributeError异常
property(fget = None, fset = None, fdel = None, doc = None)#设置一个属性,设置定义好的属性,fget:获得属性的方法,fset:设置属性的方法, fdel:删除属性的方法
eg:#修改接口是无需修改使用的方法,提高用户体验
def getSize(self):
return self.size
def setSize(self, value):
self.size = value
def delSize(self):
del self.size
x = property(getSize, setSize, delSize)
c1.x #getSize
c1.x = 1 #setSize(1)
del c1.x #defSize()
描述符:
将某种特殊类型的类的实例指派给另一个类的属性。
必须实现其中至少一个:
__get__(self, instance, owner)#用于访问属性,返回属性的值
__set__(self, instance, value)#将在属性分配操作中调用,不返回
__delete__(self, instance)#控制删除操作,不返回
以上三个函数只有通过自己的类的实例作为其他类的属性时才会被调用
为类名取别名:(类似于typedef)
新类名 = 类名
静态方法/属性:
在类中直接定义的属性都是静态属性:没有用self.出来的属性
在类中定义静态方法:在方法前一行添加:@staticmethod
1. 静态方法不会绑定到类上
2. 不需要self参数
3. 普通方法每个实例都有一个,静态方法只有一个,节省开销