面向对象之多态以及魔法函数

一:多态

【1】基础概念

(1)基础概念:

  (1)一种事物拥有多种形态:

    例如:水--->气态--->液态--->固态

  (2)在python中是多个对象可以相应同一种方法 产生不同的结果

PS:多态不是一种语法 而是一种特殊的状态 特性 即多个对象有相同的使用方法

例如:

# 案例一
class Chicken:
    def span(self):
        print(‘下鸡蛋‘)

class Duck:
    def span(self):
        print(‘下鸭蛋‘)

class Goose:
    def span(self):
        print(‘下鹅蛋‘)

j = Chicken()

y = Duck()

e = Goose()

j.span() # 下鸡蛋
y.span() # 下鸭蛋
e.span() # 下鹅蛋

# 案例二
a = ‘10‘

b = [10]

c = (10,)

print(len(a),len(b),len(c)) # 2 1 1

多态案例

(2)优点:

  (1)增加的程序的灵活性 以不变应万变 无论对象怎么变化 使用者调用方式不变

  (2)如果通过继承类 而创建一个新的类 使用者无需更改自己的代码 还是以原始方式调用

PS:继承 抽象类 鸭子类型都可以写出具备多态的代码 但是鸭子类型更加方便以及快捷

【2】内置方法

(1)isinstance:

作用:判断一个对象是否为一个类的实例

例如:

def add_num(x,y):
    # 判断整形是否为某个类
    if isinstance(x,int) and isinstance(y,int):
        return x + y
    return ‘错误的相加‘

# 情景一
 print(add_num(‘10‘,20)) # 报错 字符串与整形不能相加

# 情景二 print(add_num(‘10‘,20)) # 错误的相加

# 情景三 判断所属的类
print(add_num(10,20)) # 30

PS:

(1)参数一:所传的对象

(2)参数二:所属的类

(2)issubclass:

作用:判断一个类是否为一个类的子类

例如:

class Animal:
    def eat(self):
        print(‘动物需要吃东西!‘)

class Pig(Animal):
    def eat(self):
        print(‘猪正在吃猪食!‘)

class Tree:
    def sunshine(self):
        print(‘树在进行光合作用!‘)

def manage(animal):
    # 判断一个类是否为另外一个类的子类
    if issubclass(type(animal),Animal):
        animal.eat()
    else:
        print(‘不是动物 而是植物!‘)

pig = Pig()
tree = Tree()

manage(pig)
# 没加条件判断之前
manage(tree)  # 报错 因为tree没有继承Animal

# 添加添加判断
manage(tree) # 不是动物 而是植物!

判断一个类是否为另外一个类子类

(3)str

(1)作用:在对象被转换成字符串的时候被调用 调用的结果就是函数的返回值

例如:

class Person:
    def __str__(self):
        print(‘run‘)

        return ‘SR‘

p = Person()

# 没加返回值之前
print(p)  # 报错 希望得到一串字符串返回值

# 添加返回值
print(p)  # 执行函数代码 并且有返回值

str(p) # run
#PS:对象在被转换成字符串的时候 调用__str__函数

PS:

(1)如果对象在被转换成字符串的时候 首先会执行__str__的执行

(2)__str__执行完毕之后 在进行函数的打印

(4)del:

作用:手动删除对象的时候 或者程序结束会立马执行释放内存

使用场景:但是其作用不是用来清除解释器中的资源 而是不属于解释器的资源 例如某些文本 端口号等

例如:

class  File:
    # 创建文件的初始属性 赋值函数的地址
    def __init__(self,path):
        self.file = open(path,‘rt‘,encoding=‘utf-8‘)

    def read(self):
        # 返回读取的文件
        return self.file.read()

    def __del__(self):
        self.file.close()

file = File(‘a.txt‘)
print(file.read())
file .__del__()
print(file.read()) # 报错显示文件已经被关闭

PS:上述可以通过del删除非解释器的资源

(5)call

作用:在调用对象的时候被执行

例如:

class A:
    def __call__(self, *args, **kwargs):
        print("call run")
        print(args)
        print(kwargs)

a = A()
a(18,a = 100)

(6)solts

作用:

  (1)一种优化机制 防止浪费不必要的内存

  (2)其将不固定的属性数量变的固定了

  (3)这样解释器不会为对象创建名称空间 减少了__dict__

  (4)当类中出现了该参数 对象也不能在添加属性

例如:

import sys
class Person:
    __slots__ = [‘name‘]

    def __init__(self,name):
        self.name = name

p = Person(‘SR‘)
# print(p.__dict__) # 报错

# 加slots之前
print(sys.getsizeof(p)) # 56

# 加slots
print(sys.getsizeof(p)) # 48

# 添加新属性
p.age = 20 # 报错

(7)

(1)getattr

  作用:当用点访问属性的时候 如果属性不存在则会执行

(2)setattr

  作用:当用点设置属性的时候 会执行改函数

(3)delattr

  作用:用del 删除属性的时候 会执行改函数

(4)getattribute

  作用:当在调用属性的时候 如果属性存在则会调用该函数并且将属性值返回 如果属性不存在的情况下则会调用getattr

例如:

class A:

    def __setattr__(self, key, value):

        print("__setattr__")
        self.__dict__[key] = value

    def __delattr__(self, item):
        print("__delattr__")
        self.__dict__.pop(item)

    def __getattr__(self, item):
        print("__getattr__")
        return 1

    def __getattribute__(self, item):
        print("__getattribute__")
        # return self.__dict__[item]
        return super().__getattribute__(item)

方法演示

PS:

(1)当在__getattribute__代码块中,再次执行属性的获取操作时,会再次触发__getattribute__方法的调用,代码将会陷入无限递归,直到Python递归深度限制(重载__setter__方法也会有这个问题)

(2)为了避免无限递归,应该把获取属性的方法指向一个更高的超

(8)

(1)getitem

  作用:当使用[]调用属性的时候会执行该函数

(2)setitem

  作用:当使用[]设置属性的时候 会执行该函数

(8)delitem

  作用:当使用[]删除属性的时候 会执行该函数

例如:

class A:
    def __getitem__(self, item):
        print("__getitem__")
        return self.__dict__[item]

    def __setitem__(self, key, value):
        print("__setitem__")
        self.__dict__[key] = value

    def __delitem__(self, key):
        del self.__dict__[key]
        print("__delitem__")

a = A()
# a.name = "jack"
a["name"] = "jack"
print(a["name"])
del a["name"]
print(a["name"])

(9)运算符重载:

作用:

(1)当在python中调用某个符号的时候 python都会为该符号定义一个含义 并且调用该含义背后所对应的函数

(2)当我们需要自己定义比较规则的时候 就可以自己在子类中覆盖父类中所对应的 大于 等于 小于等方法

例如:

class Student(object):
    def __init__(self,name,height,age):
        self.name = name
        self.height = height
        self.age = age

    def __gt__(self, other):
        # print(self)
        # print(other)
        # print("__gt__")
        return self.height > other.height

    def __lt__(self, other):
        return self.height < other.height

    def __eq__(self, other):
        if self.name == other.name and  self.age == other.age and self.height == other.height:
            return True
        return False

stu1 = Student("jack",180,28)
stu2 = Student("jack",180,28)
# print(stu1 < stu2)
print(stu1 == stu2)

PS:

(1)gt 大于 lt 小于 eq等于

(2)在代码中other指的是其余对象 self作为本身

(9)上下文管理:

(1)在生活中一段话的意义要看情景 上问和下文有关联

(2)在python中上下文可以看做一个范围 某些代码只在一个范围内有效

  (1)enter 进入上下文

  (2)exit 退出上下文

例如:

class MyOpen(object):

    def __init__(self,path):
        self.path = path

    def __enter__(self):
        self.file = open(self.path)
        print("enter.....")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit...")
        # print(exc_type,exc_val,exc_tb)
        self.file.close()
        return True

(1)代码执行完毕之后 执行exit结束上下文

(2)代码执行错误也会执行exit结束上下文

(3)其会返回错误类型 错误的信息 以及错误的路径追踪信息

PS:

(1)enter返回值为对象自己

(2)exit返回值为布尔值 表示错误信息是否被处理 如果为真则表示已经处理 为假则未处理

原文地址:https://www.cnblogs.com/SR-Program/p/11267157.html

时间: 2024-10-10 00:26:57

面向对象之多态以及魔法函数的相关文章

C++中的多态与虚函数的内部实现

1.什么是多态 多态性可以简单概括为“一个接口,多种方法”. 也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可以用自己的方式去响应共同的消息.所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数.这是一种泛型技术,即用相同的代码实现不同的动作.这体现了面向对象编程的优越性. 多态分为两种: (1)编译时多态:主要通过函数的重载和运算符的重载来实现. (2)运行时多态:主要通过虚函数来实现. 2.几个相关概念 (1)覆盖.重

Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇

一.面向对象之多态 1.多态:简而言子就是多种形态或多种类型 python中不支持多态也用不到多态,多态的概念是应用与java/C#中指定传参的数据类型, java多态传参:必须是传参数的数据类型或传参的子类类型 面向对象总结: 面向对象是一种编程方式,此编程方式的实现是基于类和对象的使用 类:是一个模板,模板中包含了多个函数共使用,即类中可包含多个函数(类中的函数即叫做方法) 一般疑问: 1)什么样的代码才是面向对象? 简单来说,如果程序中的所有功能否是由 “类”和“对象”实现,那么就是面向对

php魔法函数与魔法常量的说明

魔术函数 1.__construct() 实例化对象时被调用, 当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用. 2.__destruct() 当删除一个对象或对象操作终止时被调用. 3.__call() 对象调用某个方法, 若方法存在,则直接调用: 若不存在,则会去调用__call函数. 4.__get() 读取一个对象的属性时, 若属性存在,则直接返回属性值: 若不存在,则会调用__get函数. 5.__set() 设置一个对象的属性

PKU C++程序设计实习 学习笔记3 多态与虚函数

第六章 多态与虚函数 6.1 多态和虚函数的基本概念 引言 多态是面向对象程序设计里面非常重要的这个机制.它能很有效的提高程序的可扩充性. 有些程序设计语言有被对象继承的概念,但是没有多态的概念,那这样的程序设计语言只能被称作基于对象的程序设计语言,而不能称为面向对象的语言, 比方说visual basic. 虚函数 在类的定义中,前面有 virtual 关键字的成员函数就是虚函数. class base { <span style="color:#ff0000;">vir

go面向对象之多态即接口(interface)

1.go语言的多态是用接口来实现的interface package main import "fmt" //面向对象的多态是通过接口interface来实现的,不同的对象,调用相同的接口,实现不同的效果 //go语言中,接口interface是一个自定义类型,描述了一系列方法的集合,关键字interface //接口不能被实例化 //定义接口的方法 //type 接口名字 interface { // //} //接口的名字一般以er结尾 //定义一个Personer的接口 type

python的魔法函数

hello, 大家好, 今天给大家分享一点python的魔法函数,即Python中自带双下划线的函数,虽然在大规模的软件开发中大家用的不多,当然除非你想被打(可以秀(装逼)一下), 虽然使用的不多, 但是要是能数量的运用它们的话, 没有点功力基础也是相当困难的, 正所谓没有扎实的基本功,即便南拳北腿,降龙十八掌,九阴白骨爪,乾坤大挪移全部了然于心,照样是花拳绣腿,百无一用 所以还是老老实实的把自己的基本功练好,面向对象玩的炉火纯青,其他的不过是稍加训练,跟卖艺的学几招也能称霸一片天.哈哈 牛吹的

python 30 面向对象之 多态

目录 1,mixins机制 2,子类派生的新方法中重用父类的功能 3, 面向对象之--多态 4,一些内置函数的介绍 1,mixins机制 多继承的正确打开方式:mixins机制 mixins机制核心:就是在多继承背景下尽可能地提升多继承的可读性 ps:让多继承满足人的思维习惯=>什么"是"什么 使用Mixin类实现多重继承要非常小心 首先它必须表示某一种功能,而不是某个物品,python 对于mixin类的命名方式一般以 Mixin, able, ible 为后缀 其次它必须责任

操作数据库的魔法函数

function bind(){ global $dbhost,$dbuser,$db,$dbpass; //首先我们不知道外面会传入多少个参数//可以用func_get_args()方法来获取全部传入参数,这个方法返回全部参数的数组//和func_get_args()方法相对应的其实还有一个func_num_args()来获取参数个数$args = func_get_args(); //通过使用array_shift方法,使传入的第一个参数,后后面的参数分开,其实就是把sql语句,和//后面传

面向对象编程 多态

面向对象编程 -多态 对象的多态性是指在父类中定义的属性或行为被子类继承之后,可以具有不同的数据类型或表现出不同的行为.这使得同一个属性或行为在父类及其各个子类中具有不同的语义. 多态这个概念,在 Java 中指的是变量可以指向的对象的类型,可是变量声明类型的子类.对象一旦创建,它的类型是不变的,多态的是变量. 在 PHP5 中,变量的类型是不确定的,一个变量可以指向任何类型的数值.字符串.对象.资源等.我们无法说 PHP5 中多态的是变量. 我们只能说在 PHP5 中,多态应用在方法参数的类型