ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python基础——超类&反射&装饰器&生成器

2022-08-17 01:00:46  阅读:222  来源: 互联网

标签:name python 生成器 add 超类 print class def 属性


一、超类

1.1 什么时候用到超类? 如果子类需要复用父类的代码(属性、代码)时,需要通过超类实现
class A:
    class_name = "A"  # 类的属性

    def __init__(self, name, age):
        self.name = name  # 实例的属性
        self.age = age  # 实例的属性

    def show_me(self):
        print(f"Hello,我的name是 {self.name}")
        print(f"Hello,我的age是 {self.age}")


a = A("austin", 18)
a.show_me()

# 类A 进行【扩展】:增加一个 国家 属性
class B(A):  # 继承实现扩展
    class_name = "B"
    def __init__(self, country, *args, **kwargs):
        self.country = country
        super().__init__(*args, **kwargs)  # 通过超类,实现对父类代码复用

b= B(country='China', name="sunny", age=18)
b.show_me()

 

  • super 不是代表父类;
  • super 是一个内置函数,返回了超类;
  • 沿着继承关系,从祖上一系列类中,寻找成员;
class C(B):
    class_name = "C"
    def show_class_name(self):
        print("自己class_name属性", self.class_name)
        print("继承来的class_name属性", super().class_name) # 超类的class_name
        # print("继承来的class_name属性", super(B,self).class_name)

c= C(country='China', name="sunny", age=18)
c.show_class_name()

>>>

自己class_name属性 C
继承来的class_name属性 B 

1.2 super 可以接收参数:
  • 从哪个类的祖先中找成员
  • 传递实例对象
class C(B):
    class_name = "C"
    def show_class_name(self):
        print("自己class_name属性", self.class_name)
        # print("继承来的class_name属性", super().class_name) # 超类的class_name
        print("继承来的class_name属性", super(B,self).class_name)

c= C(country='China', name="sunny", age=18)
c.show_class_name()

>>>

自己class_name属性 C
继承来的class_name属性 A

1.3 类继承关系
print(C.__mro__)

>>>
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

二、反射

反射:允许使用变量的值(而不是变量的名),对成员进行访问   1. 设置属性
setattr(A, attr_name, "B") #设置属性
2.读取属性
print(getattr(A, attr_name)) # 读取属性
3.删除属性
delattr(A,attr_name)  #删除属性
4. 判断属性
f hasattr(A,attr_name):   #属性是否存在
举例:
class A:
    class_name='A' #类属性
    age=18

attr_name="class_name"  
# attr_name="age"
print(getattr(A,attr_name))    #通过变量值访问属性

setattr(A,attr_name,'B')  #通过变量值设置属性
print(getattr(A,attr_name))   #获取属性值
delattr(A,attr_name)  #删除属性


if hasattr(A,attr_name):   #属性是否存在
    print(A.class_name)
else:
    print(f"属性:{attr_name},不存在")

三、装饰器

3.1 装饰器的原理

  • 是一个函数,参数是函数,返回值是函数
from datetime import datetime
def logs(func): # 装饰器 def f(): print(datetime.now(), func.__name__, "开始调用") func() print(datetime.now(), func.__name__, "调用结束") return f @logs # 装饰 def add(): # 被装饰函数 print("add is calling") add()

>>>

2022-08-16 23:22:43.221348 add 开始调用
add is calling
2022-08-16 23:22:43.221348 add 调用结束

规则的原因(装饰器的装饰过程)
@logs # 装饰
def add(): # 被装饰函数
    print("add is calling")

等同于

def add():  # 被装饰函数
    print("add is calling")

# 装饰的过程,被装饰函数作为参数,传递给装饰器,并且将返回值覆盖原函数
add = logs(add)  

 

3.2 被装饰函数有参数

装饰器的返回值,接收参数,并传递给【被装饰函数】
from datetime import datetime

def logs(func):  # 装饰器
    def f(*args, **kwargs):
        print(datetime.now(), func.__name__, "开始调用")
        func(*args, **kwargs)
        print(datetime.now(), func.__name__, "调用结束")

    return f

@logs
def add(x, y):  # 被装饰函数
    print("add is calling:", f"{x=}, {y=}")

add(x=2, y=2)

 3.3 装饰器怎么接收自己的参数

  创建一个函数来接收参数,然后返回原来的装饰器
from datetime import datetime

def logs(level):
    def _logs(func):  # 装饰器
        def f(*args, **kwargs):
            print(level,datetime.now(), func.__name__, "开始调用")
            func(*args, **kwargs)
            print(level,datetime.now(), func.__name__, "调用结束")

        return f
    return _logs

@logs(level="debug")
def add(x, y):  # 被装饰函数
    print("add is calling:", f"{x=}, {y=}")

add(x=2, y=2)
@logs(level="debug")
def add(x, y):  # 被装饰函数
    print("add is calling:", f"{x=}, {y=}")

 

 等同于
def add(x, y):  # 被装饰函数
    print("add is calling:", f"{x=}, {y=}")
    
add = logs(level="debug")(add)

 四 生成器

如果函数中有yield关键字,其调用结果,则返回一个生成器 生成器是一个可迭代对象,可以被for循环遍历使用 在遍历时才执行,并计算返回值
def add(a, b):
    c = a + b
    print(c)
    yield c

c = add(1, 2) 
print(c) # c是生成器

for i in c: # 生成器:在使用数据时,才产生数据
  print(f"{i=}")

>>>

3
i=3

 

 

标签:name,python,生成器,add,超类,print,class,def,属性
来源: https://www.cnblogs.com/sunny-test/p/16593517.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有