第6章 类和对象

python支持面向对象的三大特征:封装、继承、多态——用途不明,暂且记录

# 基本概念与操作

名词name定义代码举例
class一批对象的抽象A人类
对象(实例)object(instance)具体存在的实体A()

类与对象的关系:类的主要作用是重复创建具有相同特征的对象【类名()】

创建类

class 类名:    #语法上,合法即可;可读性上,由单词连缀而成,首字母大写
    "说明文档"
    执行语句    #直接执行的命令
    类变量      
    类方法

类成员

同一个类中,各成员可以互相调用,不受其位置约束

  1. 变量
    |类型|创建位置|从属于|适用范围|
    |:----|:----|:----|:----|
    |类变量|类下|类【A】|类中所有成员均可调用|
    |实例变量|方法中|类的对象【A()】|专属于特定方法|

  2. 方法
    |类型|内部变量|
    |:----|:----|
    |构造方法__init__|在类实例化之后调用|
    |普通实例方法|专属于该方法,不可在类外调用|

  • 类的实例化:实质上调用了类的构造方法,缺省时,python自带只含self参数的构造方法
class A:
    x = 1                       #类变量
    def __init__(self, y=2):    #构造方法
        self.y = y              #【y】:构造方法中的实例变量
    def B(self, z):             #普通实例方法
        print(z)                #【z】:普通实例方法的实例变量

类的基本操作

class A:
    x = 1
    def B(self): pass
a = A()
def C(self): pass
类成员操作类名【A】变量名【a】类的实例化【A()】
类变量调用A.xa.xA().x
增加A.new =a.new =-
删除del A.xdel a.x-
重新赋值A.x =--
实例变量增加a.new =
类方法调用-a.B()A().B()
增加A.new = Ca.new = C-
删除del A.Bdel a.B
  • 增加:给不存在的类成员赋值
  • 通过变量名【a】增加的实例变量只属于【a】,跟类没有关系

# self

在类方法中是必须的,绑定到类的实例,调用类方法时,不需要传入self对应的参数

类成员互相调用时,self不可缺省——原因:此时,类尚未实例化

class A:
    def b(self): pass
    def c(self): self.b()  #调用b方法时,self不可省略

绑定方法:

  1. 在类的内部,由python自动绑定
  2. 在类的外部,手动绑定:类名.类方法名(类名)
class A:    pass
def B(self):pass

A.new = B  #把方法B添加到类A中
A.new(A)   #手动绑定self与类
A.new      #调用A的新方法【new】

# 函数装饰器@

用已有的函数A修饰另一函数B,A可以是内置的函数,也可以是自定义的函数

作用:将B作为A的参数传入,然后运行A,相当于A(B),以下两段代码等效——感觉是鸡肋

代码一:

def A(a):   print(a)
def B():    pass

A(B)
>>> <function B at 0x000000000212C268>

代码二

def A(a):   print(a)

@A
def B():    pass

B
>>> <function B at 0x000000000212C268>

# 常用作函数装饰器的函数property()

功能:将方法定义成属性

语法:class property([fget[, fset[, fdel[, doc]]]])

各参数对应的函数依次为:获取属性值、设置属性值、删除属性值、属性描述信息

内置的方法:getter, setter, deleter, docstring

参数数量与函数属性的对应关系
参数数量可读可写可删除说明文档
1YESNONONO
2YESYESNONO
3YESYESYESNO
4YESYESYESYES

使用property为创建方法的属性,有两种途径

  1. 先定义方法,然后把方法作为property的参数传入
  2. 直接用property本身或property内部的函数修饰方法
class A:
    def __init__(self):
        self._x = None      #创建实例变量
    def getx(self):
        return self._x      #返回实例变量的值
    def setx(self, value):
        self._x = value     #增加新的实例变量
    def delx(self):
        del self._x         #删除实例变量
    x = property(getx, setx, delx, "说明文档")
class A:
    def __init__(self): self._x = None
    @property
    def x(self):        return self._x 
    @x.setter
    def x(self, value): self._x = value 

如果只向property传入一个参数,可以方便地创建只读属性

class A:
    def __init__(self): self._x = 1
    @property
    def B(self):  return self._x

# 隐藏和封装

python没有真隐藏,只有假隐藏

python会创建一个新类【_原类名】,把以双划线开头的成员放进去,其实还是可以访问的

# 类的继承

子类继承父类的方法,未指定时,默认继承object类。一个子类可以继承多个父类(不推荐)

继承的语法:class 子类名(父类1,父类2,…)

方法重名时的优先级:子类 > 父类;排名靠前的父类 > 排名靠后的父类

优先级低的方法可以通过类名直接调用

构造方法的继承:默认只继承第一个父类的构造方法,如果想继承多个父类的构造方法,需要为子类重写构造方法。重写时,可以用父类名直接调用父类的构造方法

class A:
    def __init__(self,x):   self.x = x
    def m(self):            print(self.x)

class B:
    def __init__(self,y):   self.y = y
    def n(self):            print(self.y)
        
class C(A,B):
    def __init__(self,x,y):
        A.__init__(self,x)
        B.__init__(self,y)

c = C(1,2)
c.m()
c.n()

类的关系

代码返回内容
base优先级最高的父类
bases所有直接父类(元组形式)
subclasses()所有直接子类(列表形式)
issubclass(A,B)检查A是否为B的子类,B可以是元组
class A: pass
class B(A): pass
class C(A): pass
print(A.__subclasses__())

>>> [<class '__main__.B'>, <class '__main__.C'>]

# 类的函数

代码作用
slots(a,b,c)
在类下第一行输入
限制对类的对象【a】的修改
只允许修改a,b,c方法/属性
type()类都是用type()函数创建的,其类型都是【type】
metaclass将某些特征应用到所有类,自动执行
  • slots的局限性:还是可以通过类名【A】直接修改类;对派生的子类无效

metaclass 用于创建类的类

步骤

  1. 设置特征。要继承type类并重写new方法
    new: 在__init__之前被调用的特殊方法,用来创建当前类的对象并返回

参数:cls - 类,name - 类名,bases - 所有父类,attrs - 所有方法、属性的合集

  1. 把特征应用到类
class A(type):
    def __new__(cls, name, bases, attrs):
        return type.__new__(cls, name, bases, attrs)
class B(metaclass = A)

多态

多态性:变量执行方法时,指向不同对象

作用:可先确定方法【A().a()】,后确定对象,程序更加灵活

class A:
    def a(self,x):      x.draw(self)  #调用draw方法的对象x稍后确定
class B:
    def draw(self,y):   print('B',y)
class C:
    def draw(self, z):  print('C',z)

A().a(B())
A().a(C())

>>>
B <__main__.A object at 0x0000000002F5DC50>
C <__main__.A object at 0x0000000002F5DC50>

定义枚举类 Enum

import enum
Season =enum.Enum(Season, ('spring', 'summer', 'fall', 'winter'))

类的对象有限且固定时,可将其定义为枚举类。如:季节只有春夏秋冬4个对象
类自带__member__属性,以字典形式返回所有实例

每个成员都有name和value两个属性,其中,value默认依次为1,2,3,4

程序报错:name ‘Season’ is not defined

isinstance(a,b)检查a是否为b的对象,B可以是元组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ailsa2019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值