首页 > 其他分享 >20.面向对象【四】

20.面向对象【四】

时间:2024-05-08 19:34:40浏览次数:13  
标签:__ 20 name self 面向对象 st1 print 属性

【一】抽象类

抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

# 所有继承父类的子类必须重写父类的某些方法,这个父类就叫抽象类
import abc
class Animal(metaclass=abc.ABCMeta):
    def __init__(self, color, foot):
        self.color = color
        self.foot = foot
    def tell(self):
        print(f"The color of this animal is {self.color}")
    # 在子类中必须重写当前的方法
    @abc.abstractmethod
    def speak(self):
        print(f'动物叫声')
class Cat(Animal):
    def __init__(self, color, foot):
        super().__init__(color, foot)
    # 如果不重写父类的方法会报错
    def speak(self):
        print('喵喵叫')
cat1 = Cat('black', '4')
cat1.tell()
# The color of this animal is black
cat1.speak()
# 喵喵叫

【二】多态与多态性

1)多态

  • 指的是一类事件有多种形态(动物:猫狗...)

2)多态性

  • 多态动态绑定在继承的背景下使用时,称为多态性

  • 多态性指在不考虑实例类型的情况下使用实例

  • 多态性在面向对象方法的表述

    • 向不同对象发同一个消息,不同的对象会产生不同的行为
    • 即每个对象可以用自己的方法去响应同种消息

3)多态性的分类

1.静态多态性

运算+表达式

2.动态多态性

import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def speak(self):
        print(f'动物叫声')
class Dog(Animal):
    def speak(self):
        print('汪汪叫')
class Cat(Animal):
    def speak(self):
        print('喵喵叫')
# 定义统一接口
def speak(obj):
    obj.speak()
dog = Dog()
cat = Cat()
speak(dog)
# 汪汪叫
speak(cat)
# 喵喵叫

4)多态性的好处

  • 增加了程序的灵活性
  • 增加了程序的可扩展性

5)鸭子类型(duck typing)

  • 是一种编程风格,决定一个对象是否有正确的接口

  • 通过强调接口而不是特定类型,设计良好的代码通过多态提高了灵活性

  • 强制重写父类方法:抽象类

    • 不依赖于继承,只需要制造出外观和行为相同对象

    • 不考虑对象类型而使用对象,

【三】绑定方法与非绑定方法

1)绑定到对象的方法

  • 没有装饰器的方法
class Student(object):
    def __init__(self, name):
        self.name = name
    def talk(self):
        print(f'Hello {self.name}')
st1 = Student('diva')
# 对象可直接调用绑定给对象的方法
st1.talk()  # Hello diva
# 类调用绑定给对象的方法,需主动传入一个生成的对象
Student.talk(st1)  # Hello diva

2)绑定给类的方法

  • 用classmethod装饰器装饰的方法。
class Student(object):
    def __init__(self, name):
        self.name = name
    @classmethod
    def talk(cls, name):
        obj = cls(name)
        print(f'Hello {obj.name}')
print(Student.talk)  
# <bound method Student.talk of <class '__main__.Student'>>
st1 = Student('diva')
# 对象调用绑定给类的方法, 默认将实例化得到当前对象的类自动传入
st1.talk('diva')  # Hello diva
# 类调用绑定给类的方法,类可以直接调用,默认将调用当前方法的类自动传入
Student.talk('diva')  # Hello diva

3)非绑定方法

  • 用staticmethod装饰器装饰的方法
  • 不与类或对象绑定,类和对象都可以调用,但是没不会自动传值
class Student(object):
    def __init__(self, name):
        self.name = name
    @staticmethod
    def talk():
        print("Hello")
st1 = Student("diva")
# 对象调用非绑定方法, 不用传任何参数,和普通函数一样
st1.talk()  # Hello
# 类调用非绑定方法, 不用传任何参数,和普通函数一样
Student.talk()  # Hello

【四】反射

  • 反射是一种程序可以访问、检测和修改其本身状态或行为的方式
  • 在Python中,反射主要指通过字符串映射自己的内部是否具有某种属性
class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def tell(self):
        print(f"{self.name} is {self.age} years old")
    @classmethod
    def talk_c(cls, name):
        obj = cls(name)
        print(f'Hello {obj.name}')
    @staticmethod
    def talk_s():
        print("Hello")
st1 = Student('diva', 20)

1)getattr(obj,key)

  • 获取对象的属性值,如果属性不存在,可提供默认值
# 数据属性:在对象中映射数据属性时,如果对象中存在当前属性值则直接将属性值拿出
result = getattr(st1, 'name')
print(result)  # diva

# 函数属性:如果存在则直接获取当前函数属性的内存地址,可直接调用
result = getattr(st1, 'tell')
print(result)
# <bound method Student.tell of <__main__.Student object at 0x000002613E7CD0D0>>
result()
# diva is 20 years old

# 不存在:会直接报错

2)hasattr(obj,key)

  • 判断对象是否具有指定属性
# 数据属性:在对象中映射数据属性时,如果对象中存在当前属性值,则返回True
result = hasattr(st1, 'name')
print(result)  # True

# 函数属性:如果对象中存在当前属性名对应的数据属性,则返回True
result = hasattr(st1, 'tell')
print(result)  # True

# 不存在:返回False

3)setattr(obj,key,value)

  • 设置对象的属性值
# 数据属性:向对象设置属性名和属性值时,存在则替换,不存在则新增
result = setattr(st1, 'name', 'a')
print(result)  # None
print(st1.name)  # a
result = setattr(st1, 'sex', 'man')
print(result)  # None
print(st1.sex)  # man

# 函数属性:如果对象中存在当前属性名对应的数据属性,则返回True
def read():
    print(f'读')
result = setattr(st1, 'read', read)
print(result)  # None
print(hasattr(st1, 'read'))  # True
print(getattr(st1, 'read'))  # <function read at 0x000002089A6E04A0>
getattr(st1, 'read')()  # 读
st1.read()  # 读

4)delattr(obj,key)

  • 删除对象属性
# 数据属性:在对象删除时,如果对象中存在则直接删除
print(hasattr(st1, 'name'))  # True
result = delattr(st1, 'name')
print(result)  # None
print(hasattr(st1, 'name'))  # False

# 函数属性:
# 如果参数是当前对象,则无法删除
result = delattr(st1, 'tell')# 报错
# 如果参数是当前类,则可以删除
result = delattr(Student, 'tell')
print(result)  # None
print(hasattr(Student, 'tell'))  # False

# 不存在:直接报错

【五】面向对象内置方法(魔法方法)

__init__	:初始化类时触发
__del__		:删除类时触发
__str__		:str函数或者print函数触发
__repr__	:repr或者交互式解释器触发
__doc__		:打印类内的注释内容
__enter__	:打开文档触发
__exit__	:关闭文档触发
__getattr__ :访问不存在的属性时调用,	对象.属性
__setattr__ :设置实例对象的一个新的属性时调用,	对象.属性 = 属性值
__delattr__ :删除一个实例对象的属性时调用,	del 对象.属性
__setitem__	:列表添加值,	对象[属性]=属性值
__getitem__ :将对象当作list使用,	对象[属性]
__delitem__	:列表删除值,	del 对象[属性]

标签:__,20,name,self,面向对象,st1,print,属性
From: https://www.cnblogs.com/Mist-/p/18180710

相关文章

  • 20244-zuo-ti-ji-lu
    4.7CF1648D设$dp_i$为从$(1,1)$到$(2,i)$的最小代价。答案为$\maxdp_i+s3_n-s3_{i-1}$。$$dp_i=max(\max_{l_x\lei}dp_{l_x-1}+s2_i-s2_{l_x-1}-w_x,\max_{l_x\lej\lei}s1_j+s2_i-s2_{j-1}-w_x)$$前面线段树维护dp值,按转移顺序区间max,单点查。后面从后往前枚......
  • 20243-zuo-ti-ji-lu
    二月没写3.01P3379先考虑完全二叉树的lca求法。中序遍历分配编号。设第$k$位是$u\oplusv$最左边的$1$,则$lca(u,v)$是$u,v$的$k$位以左、第$k$位是$1$,$k$位以右是$0$。将树上lca转到完全二叉树上。先序遍历,设$h_u$表示$dfn_u$的末尾连续$0$数,$l_u$......
  • 20241-zuo-ti-ji-lu
    1.08CF235C求每个询问串的所有循环同构在主串中出现的次数总和。向后遍历可做,现在需要删掉开头。删除开头$l$减$1$,如果$l=len_{lnk_p}$,那$p$就不能再在这个节点,$p=lnk_p$。1.09P4094子串$s[a...b]$的所有子串和$s[c...d]$的最长公共前缀的长度的最大值。二分答案......
  • at_joi2020ho_b-ti-jie
    AT_joi2020ho_b另,这道题也是P6878,数据应该是强一些。思路枚举起始的位置$i$,显然$c[i]=J$,即枚举$J$的位置。为了使操作三删除中间的字符更少,问题转换对于为从$i$起的最短的包含一个$k$阶字符串的字符串的长度。有点绕。那么从$i$位置起,向后找$k-1$个$J$,记录位置......
  • 2024.5 做题记录
    五一之后临时决定要来脱产。谢谢所有认可我的决定,支持我的人。P1935[国家集训队]圈地计划注意到相邻两项不同就会产生贡献的条件不好处理,所以考虑对行列进行黑白染色,将一种颜色格子的\(a,b\)交换,这样条件就变成了相邻两项不同才会产生贡献。然后套用文理分科的做法就可......
  • buuctf-pwn-ciscn_2019_c_1-ret2libc
    检查一下保护情况ida里选项2,3都没有什么重要的信息,直接看选项1发现栈溢出漏洞,不过程序对输入的字符串有一个异或加密,这里可以构造异或后的payload,利用程序来解密,或者可以直接在payload第一位加上'\x00',直接截断payload后面的异或操作用cyclic测一下溢出点,得到88找一下system......
  • P1435 [IOI2000] 回文字串
    原题链接题解1.把字符串倒过来,记作\(S_1\)其最大公共子串是回文串,所以这部分可以不用求,字符串长度减去最大公共子串的长度就是答案2.怎么求最大公共子串的长度呢?假设我们已经知道字符串a和字符串b及其所有子串的lbs,此时往字符串b末尾添加一个字符c变成字符串b1,而字符串a中以......
  • [BJDCTF2020]EzPHP 审计绕过
    今天来个难点的题。点击查看代码<?phphighlight_file(__FILE__);error_reporting(0);$file="1nD3x.php";$shana=$_GET['shana'];$passwd=$_GET['passwd'];$arg='';$code='';echo"<br/><font......
  • P10429 [蓝桥杯 2024 省 B] 拔河 题解
    思路通过动态规划计算出所有连续子序列的力量值之和,并将其存储在一个数组中然后排序,遍历一遍数组,找到相邻两个力量值之和的差的绝对值的最小值,然后输出这个答案就行了。时间复杂度大概是\(O(n^2\logn)\)。来个python的代码defmin_power_diff(n,a):#计算所有连续子序列......
  • Java面向对象04——三大特性之多态
    多态1、什么是多态在Java中,多态是面向对象编程中的一个重要概念,它允许不同类型的对象对同一方法进行不同的实现。具体来说,多态性指的是通过父类的引用变量来引用子类的对象,从而实现对不同对象的统一操作。2、多态实现的条件在Java中,要实现多态性,就必须满足以下条件:继承关......