首页 > 其他分享 >组合,反射,魔术方法

组合,反射,魔术方法

时间:2023-10-10 21:33:24浏览次数:22  
标签:__ 反射 name 组合 self 魔术 print age def

组合,反射,魔术方法

  1. 组合
  2. 反射
  3. 魔术方法

组合

什么是组合?
	组合就是,一个对象拥有一个属性,该属性的值是另外一个对象.
 """什么场景下使用继承? 什么场景下使用组合?"""
继承一般情况用在:什么是什么的情况 is
组合一般用在:什么有什么的情况 has
class Foo:
    def __init__(self, m):
        self.m = m

class Bar():
    def __init__(self, n):
        self.n = n
"""一个对象拥有一个属性,该属性的值是另外一个对象."""
obj=Bar(10)
obj1 = Foo(20)
# 超级对象,通过一个属性可以访问到另外一个对象的值
obj.x=obj1

print(obj.x.m)  

案例


组合案例:选课

class People():#父类
    school = 'SH'

    def __init__(self, name, age, gender, course_name=None, course_price=None, course_period=None):
        self.name = name
        self.age = age
        self.gender = gender
        # self.course_name = course_name
        # self.course_price = course_price
        # self.course_period = course_period
class Admin(People):#管理员
    def __init__(self, name, age, gender):
        super().__init__(name, age, gender)

class Course():#科目
    def __init__(self, name, price, period):
        self.name = name
        self.price = price
        self.period = period


python=Course('python', 10000, '6mon')#添加科目
linux=Course('linux', 20000, '5mon')
# print(python.name)
# print(python.price)
# print(python.period)

class Student(People):
    #学生
    def __init__(self, name, age, gender, course=None):
        super().__init__(name, age, gender)
        if course is None:
            course = []
        self.course = course


stu = Student('kevin', 20, 'male')
stu.course.append(python.name)#进行组合
stu.course.append(linux.name)#组合
print(stu.course) # [<__main__.Course object at 0x000001F258F86B80>, <__main__.Course object at 0x000001F258F511C0>]
# stu.course: []
for i in stu.course:
    print(i)

class Teacher(People):#老师
    def __init__(self, name, age, gender, level):
        super().__init__(name, age, gender)
        self.level = level


tea = Teacher('ly', 19, 'female', 10)
# print(tea.course_name)
tea.course=linux#创建一个course,将linux组合
print(tea.course.period)
print(tea.course.name)
print(tea.course.price)

反射

在Python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用(Python中一切皆对象,类和对象都可以用下述四个方法)

四个内置函数:
    getattr: 获取属性 ##### 用的最多
    setattr:设置属性
    hasattr:判断是否有某个属性
    delattr:删除

getattr 获取属性

class Student():
    school = 'SH'

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

    def func(self):
        print('from func')

    def index(self):
        print('from index')
stu = Student('kevin', 20)
# attr=input('请输入你要操作的属性名:')
"""反射:就是通过字符串的形式来操作对象的属性"""
# 1. 获取属性
"""当你查询的属性不存在的时候,如果给了第三个参数,就返回第三个参数"""
print(stu.school)
res = getattr(stu, 'school1', 666)
print(res)
res1=getattr(stu,'shool',666)
print(res1)#666
res2=getattr(stu,'name')
print(res2)
### 函数的用法

"""必须掌握!!!!!!"""
res=getattr(stu, 'func1', stu.index)#等同于stu.func1,不存在该属性则返回默认值stu.index
res()

setattr:设置属性

### 设置
class Student():
    school = 'SH'

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

    def func(self):
        print('from func')

    def index(self):
        print('from index')
stu = Student('kevin', 20)
setattr(stu, 'x', 666) # stu.x=666
print(stu.__dict__)#{'name': 'kevin', 'age': 20, 'x': 666}

hasattr:判断是否有某个属性

#判断

class Student():
    school = 'SH'

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

    def func(self):
        print('from func')

    def index(self):
        print('from index')
stu = Student('kevin', 20)
print(hasattr(stu, 'func'))#True
print(hasattr(stu,'qwe'))#False
if hasattr(stu, 'func'):
    getattr(stu, 'func')()
else:
    pass

delattr:删除

class Student():
    school = 'SH'

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

    def func(self):
        print('from func')

    def index(self):
        print('from index')
stu = Student('kevin', 20)

delattr(stu, 'name')

print(stu.__dict__)#{'age': 20}

魔术方法

init str,repr

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

    """
        1. 打印对象的时候,输出对象的时候会自动触发类中得__str__方法
        2. 返回值必须是字符串形式
        3. 如果它跟__repr__方法同时存在,__str__的优先级更高
    """
    def __str__(self): # 这个用的是最多的
        print('str')
        return 'from str'

    def __repr__(self):
        print('repr')
        return 'from repr'
wqe=Student('qwe',12)
print(wqe)#str  from str

# print('repr:', repr(wqe))
print('str:', str(wqe))#str  str: from str

del

class MySQL:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port
        self.f = open('a.txt', 'w')
    """
    1.当你删除对象的时候会触发__del__的执行
    2. 当整个脚本的程序都执行完毕的时候,也会触发__del__的执行
    3. 一般用在用来在对象被删除时自动触发回收系统资源的操作
    """
    def __del__(self):
        print('from _del')
        self.f.close()


mysql = MySQL('127.0.0.1', 3306)

issubclass方法用于判断参数 class 是否是类型参数 classinfo 的子类

class Foo:
    pass
class Bar(Foo):
    pass
class Bar1():
    pass
print(issubclass(Bar1, Foo))

__doc__注释无法继承

class Foo:
    """
    '我是描述信息asdasd'
    '我是描述信息asdasd'
    '我是描述信息asdasd'
    """

    pass
class Bar(Foo):
    pass
print(Foo.__doc__)
    # '我是描述信息asdasd'
    # '我是描述信息asdasd'
    # '我是描述信息asdasd'
print(Bar.__doc__)
#None

enter和exit 上下文管理器with原理

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

    def __enter__(self):
        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
        # return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代码块执行完毕时执行我啊')

"""with它可以用在很多地方,但是,出现with语句后面的对象中得类必须要声明__enter__和__exit__"""

with Open('a.txt') as f:
    print('=====>执行代码块')
    print('=====>执行代码块')
    print('=====>执行代码块')
    print('=====>执行代码块')
    print('=====>执行代码块')
    # print(f,f.name)
    
简答题:先聊聊with 的用法? 问with上下文管理协议的执行原理? 为什么打开文件只会可以自动关闭?请说出原因
class Open:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
        # return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代码块执行完毕时执行我啊')
        print(exc_type) # 异常类型
        print(exc_val) # 异常值
        print(exc_tb) # 追溯信息
        return True # 如果你在这个方法里面返回了True,with代码块中出现了异常,就相当于没有出现异常

"""with它可以用在很多地方,但是,出现with语句后面的对象中得类必须要声明__enter__和__exit__"""

# with Open('a.txt') as f:
#     print('=====>执行代码块')
#     print('=====>执行代码块')
#     print('=====>执行代码块')
#     print('=====>执行代码块')
#     print('=====>执行代码块')
#     # print(f,f.name)
"""如果with代码块中出现了异常,则with语句之后的代码都不能正常执行"""
with Open('a.txt') as f:
    print('=====>执行代码块')
    raise AttributeError('***着火啦,救火啊***') # 抛出异常,主动报错
print('0'*100) #------------------------------->不会执行

setattr 设置 ,delattr 删除,getattr查看

点语法

__setattr__,__delattr__,__getattr__

class Foo:
    x=1
    def __init__(self,y):
        self.y=y

    """当你找的属性不存在的时候,会触发__getattr__,但是必须是点语法的时候才会"""
    def __getattr__(self, item):
        print('----> from getattr:你找的属性不存在')


    def __setattr__(self, key, value):
        print('----> from setattr')
        # self.key=value # self.a=20
        # self.key=value #这就无限递归了,你好好想想
        self.__dict__[key]=value #应该使用它


    def __delattr__(self, item):
        print('----> from delattr')
        # del self.item #无限递归了
        self.__dict__.pop(item)

obj=Foo(10)
# obj.z
obj.a=20
print(obj.a)

del obj.a

setitem,getitem,delitem__

中括号取值时

__setitem__,__getitem,__delitem__

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

    """当你通过中括号获取对象的属性的时候,会自动触发__getitem__"""
    def __getitem__(self, item):
        print('__getitem__')
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        # key:age
        # value:18
        print('__setitem__')
        self.__dict__[key] = value
        #  self.__dict__['age'] = 18

    def __delitem__(self, key):
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
        pass

    # def __delattr__(self, item):
    #     print('del obj.key时,我执行')
    #     self.__dict__.pop(item)
obj=Foo('tom')
# print(obj.name)

# obj['name']
obj['age'] = 18
# obj.age=18
print(obj.age)

del obj['age']

call

class Foo:

    def __init__(self):
        pass
    #### 当对象加括号的时候会触发__call__的执行
    def __call__(self, *args, **kwargs):
        print('__call__',*args)


obj=Foo()
print(obj)#<__main__.Foo object at 0x000002CCFDE2BF70>
obj('qe')#__call__ qe

标签:__,反射,name,组合,self,魔术,print,age,def
From: https://www.cnblogs.com/zhangfanshixiaobai/p/17755797.html

相关文章

  • 【python】魔术方法大全(四)——类构建篇
    这期我们来聊聊和class建立有关的魔术方法。__init_subclass__魔术方法__init_subclass__是Python3.6新增的一个特殊方法,用于定义一个类(基类)被继承时所执行的逻辑。当一个类被定义为另一个类(基类)的子类时,它会自动调用__init_subclass__方法。__init_subclass__方法定义......
  • Python 反射
    反射通过字符串映射或修改程序运行时的状态、属性、方法,有以下4个方法。hasattr(obj,name_str)#判断一个对象里是否有对应的name_str字符串的方法映射getattr(obj,name_str)#根据字符串去获取obj对象里的对应的方法的内存地址setattr(obj,"y",z),isequivalent(相当于)(to)......
  • 互联网大厂+公务员组合的家庭应该是很多人羡慕的组合吧?
    夫妻二人一个编制内,一个编制外。先说说我老公的收入。我老公是四级警长,每月到手一万多点。年终补贴大概25K左右。年底加上十三个月工资和每年休假的钱,每月有个14K+,全年合计存到手有个16W多。我,之前是阿里P7,年薪税后50W左右。去年被优化,目前入职一家中型互联网公司,年薪没涨,依然50W......
  • Composite 组合模式简介与 C# 示例【结构型3】【设计模式来了_8】
    〇、简介1、什么是组合设计模式?一句话解释:  针对树形结构的任意节点,都实现了同一接口,他们具有相同的操作,可以通过某一操作来遍历全部节点。组合模式通过使用树形结构来组合对象,用来表示部分以及整体层次。组合模式属于结构型模式,多用于递归。官方意图描述:将对象组合成树形......
  • 【愚公系列】2023年10月 二十三种设计模式(八)-组合模式(Composite Pattern)
    ......
  • 组合数学习笔记
    一些式子\[(1+x)^\alpha=\sum_{i=0}\binom{\alpha}{i}x^i\\\binomnk=\fracnk\binom{n-1}{k-1}\\\binomnk=\binomn{k-1}+\binom{n-1}{k-1}\\\binomnm=(-1)^m\binom{m-n-1}m\\\binomnkk^{\underlinem}=\binom{n-m}{k-m}n^{\under......
  • 反射简介(Reflecyion)
    反射: 优点:可以实现动态创建对象和编译,灵活性好缺点:对性能有影响,反射基本是一个解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的需求,这些操作总是会慢于直接执行相同的操作。反射主要的API:Class ......
  • 记一次itflow 反射型XSS漏洞挖掘
    引言水一篇文章,单纯记录一下开源项目漏洞挖掘历程,本文介绍了一次对某开源项目的反射型XSS漏洞的挖掘,此开源项目是一个信息技术管理平台,XSS插入点为expenses.php接口中的dtf参数。漏洞挖掘GET请求接口点,dtf参数进行XSS防御,但没有完全过滤敏感字符和函数,造成了XSS漏洞,该参数......
  • Java的反射机制
    Java的反射机制前言能够分析类能力的程序称为反射,反射机制可以用来:在运行程序时分析类的能力;在运行时检查对象;实现泛型数组操作代码;利用Method对象;Class类在程序运行期间,Java运行时系统始终为所有对象维护一个「运行时类型信息标识」。这个信息会跟踪每个对象所属的类,J......
  • PHP7 常用的魔术方法整理
    php7魔术方法有哪些?魔术方法是一种特殊的方法,当对对象执行某些操作时会覆盖PHP的默认操作。PHP保留所有以 __ 开头的方法名称。因此,除非覆盖PHP的行为,否则不建议使用此类方法名称。php7魔术方法有:__constract:在实例化一个类时,触发__destruct:在一个实例对象被销毁的......