Chapter11 python进阶——类

一、类

(一)一切皆对象

类的名称:类名

类的属性:一组数据

类的方法:允许对类进行操作的方法(行为)

 

(二)封装、抽象、实例化

(1)数据集中到一个对象叫封装。通过对象的属性封装数据。

(2)根据业务需求抽象出所需要的类,明确每个对象的职责,在类中定义职责所需要的方法。定义类的方法时,第一个参数一定是self。或者说当看到函数传入的第一个参数时self,可以推测这个函数是类的方法。

(3)实例化、属性赋值、方法调用

(4)实例化时解释器会自动调用__new__()构造对象,然后调用__init__()初始化。

 

(三)魔法方法

在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法

__init__(self[,…])中的self参数不需要开发者传递,解释器会自动把当前的对象引用传递进去

当使用print输出对象的时候,如果定义了__str__()方法,将对象转化为字符串输出,即打印出该方法中return的数据,而不是打印对象的内存地址。

在内存中销毁一个对象时python中自动调用__del__()方法:当有1个变量保存了对象的引用时,该对象的引用计数就会加1,反之亦是,删除会减1。当该对象引用计数变为0或程序结束时,会调用__del__()方法。

获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list。仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),可以直接操作一个对象的状态。比如,获得一个str对象的所有属性和方法:

>>>dir('ABC')

['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

 

(四)方法或属性命名中的下划线

xx:共有变量

_x:单前置下划线:私有化属性或方法

__xx:双前置下划线:避免与子类中的属性命名冲突,无法再外部直接访问(名字重整所以访问不到)

__xx__:双前后下划线:用户名字空间的魔法对象或属性。例如:__init__,不要自己发明这样的名字

xx_:单后置下划线:用于避免与Python关键词冲突

通过name mangling(名字重整)目的就是以防子类意外重写基类的方法或者属性。如_Class__object机制就可以访问private了。

 

_x是在模块导入的时候不会将方法导入

 

(五)隐藏属性(私有)示例

self.__xxxx

在类的外部无法被访问。要访问必须回到类中定义一个获取方法。

使用property简化getter和setter操作。参考《使用@property

@property是一个装饰器,实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@xxx.setter。

 

 

(六)隐藏方法(私有)示例

def __xxxx():

在类的外部无法被调用(原因:名字重整)

 

(七)继承与多继承

可以通过调用print(xxx.__mro__)查看多继承下的优先级

 

(八)重写

子类也定义了与父类相同的方法名,叫做重写,会优先调用子类的方法

当子类的__init__()被重写时,如果仍想调用父类的__init__(),可以添加super().__init__()方法。同样的,有super().__xxx__()方法

 

(九)类属性一旦定义就存在,也分为公共类属性和私有类属性;对象属性只有在对象定以后才有

 

(十)类方法与静态方法

方法中的self是类本身,调用方法时传的值也必须是类的公有属性,就是说类方法只能操作类本身的公有字段

class A(object):
    @classmethod     
    #类方法要在方法上面加一个修饰器,类方法的参数xxx(一般用cls,就像对象方法用self),代表当前的类
    def test(xxx):
        ……
        xxx.属性             #等同于操作A.属性
        ……
A.test()
#可以在类的方法中修改类属性

静态方法:通过类直接调用,不需要创建对象,不会隐式传递self。

class A(object):
    @staticmethod    
    #静态方法,属于类,没有类似self,cls这样的默认传递的参数,可以通过类名来调用
    def test():
        ……

 

(十一)__new__()方法

__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器自动提供

__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例

__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其他初始化的动作,__init__不需要返回值

我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节

 

(十二)动态语言:可以在运行的过程中,修改代码

可以做的事情:

①为对象动态添加属性

注意为对象动态添加的属性仅适用于该对象

要使其他对象也能用需添加类属性:类名.属性 = xxx

②为类动态添加方法

class Person(object):
    def __init__(self,name = None,age = None):
        self.name = name
        self.age = age
    def eat(self):
        print(*eat food*)

>>>def run(self,speed):
        print('%s在移动,速度是%d km/h'%(self.name,self,speed))
>>>P1 = Person('小丽','25')
>>>import types
>>>P1.run = types.MethodType(run,P1)
>>>P1.run(180)
        小丽在移动,速度是180km/h

注意上述方法添加的方法仅适用于该对象

要使其他对象也能用需添加类属性:@classmethod 或 @staticmethod

 

(十三)限制访问__slots__

要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__

限制修改对象的属性:

(十四)定制类、枚举类、元类

参考《定制类》《使用枚举类》《使用元类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值