Python 关于面向对象

面向对象具有三大特征

(一)、封装

把很多数据封装到一个对象中,把固定功能的代码封装到⼀个代码块函、数、对象, 打包成模块,这都属于封装的思想。

在Python语言中,所谓的私有,不过是一种假象。当我们在类中定义私有成员时,在程序内部会将其处理成_类名 + 原有成员名称的形式。也就是会将私有成员的名字进行一下伪装而已,如果我们使用处理之后的名字,还是能够进行访问的.程序:私有的伪装

  • xx: 公有变量
  • _x: 保护变量,只能在类的内部和类的子类,实例中使用
  • __xx: 私有变量,双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访 问(名字重整所以访问不到)
  • __xx__: 双前后下划线,用户名字空间的魔法对象或属性。例如:__init__ , __ 不要自己发明这样的名字(通过name mangling(名字重整(目的就是以防子类意外重写基类的方法或者 属性)如:_Class__object)机制就可以访问private了)
  • xx_: 单后置下划线,用于避免与Python关键词的冲突
class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_name(self):
        return self.__name

    def get_age(self):
        return self.__age


p = Person('Tom', 22)
# print(p.__name) # 报AttributeError异常
print(p.get_name())  # Tom
print(p.get_age())  # 22

# _Class__object任然可以获取属性
print(p._Person__name)  # Tom
(二)、继承

继承可以使子类拥有父类的属性和方法,并且可以重写这些方法,加强代码的复用性,python中子类可以有多个父类,但是不建议这样使用,一般会产生重复调用的问题,Super().方法名,可以调用父类的方法(不用传参,作用是调用父类的方法,传的是子类实例的值)

class Animal:
    def eat(self):
        print('Animal eat')

    def run(self):
        print('Animal run')


class Dog(Animal):
    def dog_call(self):
        print('dog_call')


class Cat(Animal):
    def cat_call(self):
        print('cat_call')


d = Dog()
d.dog_call()  # dog_call
d.eat()  # Animal eat
(三)、多态

指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式

因为Python是鸭子类型,因此,多态在Python中体现的不明显

class Animal:
    def eat(self):
        print('Animal eat')

    def run(self):
        print('Animal run')


class Dog(Animal):
    def call(self):
        print('Dog call')


class Cat(Animal):
    def call(self):
        print('Cat call')


def call(obj):
    obj.call()


c = Cat()
d = Dog()
call(c)  # Cat call
call(d)  # Dog call

类成员

描述:
  • 属性
    • 普通属性
    • 静态属性
  • 方法
    • 普通方法
    • 类方法
    • 静态方法
  • property属性
代码演示:
class Simple:
    # 静态字段
    static_field = '这是一个静态字段'

    def __init__(self, normal_field):
        # 普通字段
        self.normal_field = normal_field

    # 普通方法
    def method(self):
        print('这是一个普通方法')

    # 类方法
    @classmethod
    def class_method(cls):
        print('这是一个类方法')

    # 静态方法
    @staticmethod
    def static_method():
        print('这是一个静态方法')

    # 定义属性:获取数据
    @property
    def prop(self):
        return self.__value

    # 设置数据
    @prop.setter
    def prop(self, value):
        self.__value = value

    # 删除数据
    @prop.deleter
    def prop(self):
        del self.__value


s = Simple('这是一个普通字段')
print(s.normal_field)
print(s.static_field)
s.method()
Simple.class_method()
Simple.static_method()

输出信息

这是一个普通字段
这是一个静态字段
这是一个普通方法
这是一个类方法
这是一个静态方法
  • 普通属性属于对象
  • 静态属性属于类
  • 普通方法:由对象调用,有self参数,调用方式时,将调用方法的对象赋值给self
  • 类方法:由类调用,有cls参数,调用方法事件,将调用方法的类赋值给cls
  • 静态方法:由类调用,无默认参数
  • property属性:在普通方法上添加@property装饰器,setter装饰器赋值,getter装饰器取值

内置方法

描述:
类的内建属性和方法说明触发方式
init构造初始化函数创建实例后,赋值时使用,在__new__后
new生成实例所需属性创建实例时
class实例所在的类实例.class
str实例字符串表示,可读性print(类实例),如没实现,使用repr结果
repr实例字符串表示,准确性类实例 回车 或者 print(repr(类实例))
del析构del删除实例
dict实例自定义属性vars(实例.dict)
doc类文档,子类不继承help(类或实例)
getattribute属性访问拦截器访问实例属性时
bases类的所有父类构成元素类名.bases

说明:

__getattr__:当一般位置找不到attribute的时候,会调用getattr,(有返回值)返回一个值或AttributeError异常.
__getattribute__:无条件被调用,通过实例访问属性.

代码演示:
class Person:
    # 构造方法
    def __new__(cls, *args, **kwargs):
        print('__new__')
        return super().__new__(cls)  # 如果没有调用父类的构造函数,初始化函数是不会被调用的

    # 初始化方法
    def __init__(self, name, age):
        print('__init__')
        self.name = name
        self.age = age

    # 对象输出
    def __str__(self):
        return '我的名字%s,年龄%d' % (self.name, self.age)

    # 对象当函数调用时执行
    def __call__(self, *args, **kwargs):
        print('__call__')
        return self.name

    # 释放对象时执行
    def __del__(self):
        print('__del__')


p = Person('Tom', 22)
print(p)
print(p())

输出信息

__new__
__init__
我的名字Tom,年龄22
__call__
Tom
__del__
__getattr__和__getattribute__关系

当访问某个实例属性时, getattribute会被无条件调用,如未实现自己的getattr方法,会抛出AttributeError提示找不到这个属性,如果自定义了自己getattr方法的话,方法会在这种找不到属性的情况下被调用 。

一般重写__getattr__方法

class Person:
    def __init__(self):
        self.name = 'Jim'

    def __getattribute__(self, item):
        print('item:%s' % item)
        if item == 'name':
            return '调用getattribute'
        else:
            return object.__getattribute__(self, item)

    def __getattr__(self, item):
        print('__getattr__')
        return 'default'

测试一:

p = Person()
print(p.name)

输出信息:
item:name
调用getattribute

测试二:

p = Person()
print(p.name2)

输出信息:
item:name2
__getattr__
default
__getattribute__的坑
class Person:
    def __getattribute__(self, item):
        print('__getattribute__')
        if item.startswith('a'):
            return 'hahaha'
        else:
            return self.test # 这里会陷入递归调用

p = Person()
print(p.b)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值