layui根据name获取对象_面向对象高级

本文详细介绍了Python面向对象的高级特性,包括isinstance和issubclass的使用、反射机制、类的内置方法(如__str__、__del__、__setattr__等)、描述符、装饰器、以及迭代器、上下文管理器等。通过这些特性,可以实现更灵活的代码设计和对象操作。
摘要由CSDN通过智能技术生成

09042d4359aecb0436c58142312f832a.png
  1. isinstance(obj,cls)和issubclass(sub,super)
  2. 反射 hasattr()、setattr()、getattr()、delattr()
  3. 反射模块 __import__和importlib模块
  4. __str__和__del__
  5. __setattr__、__delattr__、__getattr__
  6. 二次加工标准类型(包装、授权)
  7. __getattribute__
  8. __setitem__和__getitem和__delitem__([]拦截方法)
  9. __format__(自定义格式化对象的字符串)
  10. __str__和__repr__
  11. __del__(析构方法)
  12. __doc__(类的注释信息)
  13. 描述符(__get__,__set__,__delete__)
  14. 类的装饰器
  15. 通过描述符+装饰器限制参数类型
  16. 自制@property、@classmethod、@staticmethod
  17. __call__
  18. __init__和__new__(重点)
  19. __module__和__class__
  20. __slots__和__dict__
  21. __all__
  22. 实现迭代器(__next__和__iter__)
  23. 上下文管理器(__enter__和__exit__)
  24. __len__
  25. __hash__
  26. __eq__

isinstance和issubclass

isinstance(obj,cls)检查是否obj是否是类 cls 的对象

ll = [1, 2, 3]
print(isinstance(ll, list))
dic = {
    'name': 'lqz'}
print(isinstance(dic, dict))
结果:
True
True

isinstance和type的区别:
# isinstance比type强大在,它可以判断带有继承关系的类的对象,type只能判断所属类的对象
class A:
    pass
 
class B(A):
    pass
 
isinstance(A(), A)    # returns True
type(A()) == A        # returns True
isinstance(B(), A)    # returns True
type(B()) == A        # returns False

isinstance和type的区别:

  • type() 不认为子类对象属于父类的类型,不考虑继承关系
  • isinstance() 认为子类对象属于父类的类型,会考虑继承关系

如果要判断对象和类的关系推荐使用 isinstance()

issubclass(sub, super)检查sub类是否是 super 类的派生类(子类)

#单层单继承:

class Mydic(dict):
    pass

print(issubclass(Mydic, dict))
print(issubclass(Mydic, list))
print(issubclass(Mydic, object))

结果:
True
False
True

#单层多继承:是所有父类的派生类

class Foo:
    pass

class Mydic(dict, Foo):
    pass

print(issubclass(Mydic, dict))
print(issubclass(Mydic, Foo))

结果:
True
True

#多层单继承:是所有直接或间接父类的派生类

class Animal:
    pass

class Dog(Animal):
    pass

class TDog(Dog):
    pass

print(issubclass(TDog, Dog))
print(issubclass(TDog, Animal))

结果:
True
True

反射

python是动态语言,而反射(reflection)机制被视为动态语言的关键。

python面向对象中的反射指在程序的运行状态中通过字符串的形式操作对象相关的属性。由于python中的一切事物都是对象,所以都可以使用反射。这种动态获取程序信息以及动态调用对象的功能称为反射机制。

首先通过内置函数dir获取任意一个类或者对象的属性列表,列表中全为字符串格式

>>> class People:
...     def __init__(self,name,age,gender):
...         self.name=name
...         self.age=age
...         self.gender=gender
... 
>>> obj=People('egon',18,'male')
>>> dir(obj) # 列表中查看到的属性全为字符串  相当于obj.__dir__()
[......,'age', 'gender', 'name']
>>> obj.__dict__  # 属性字典
{
    'name': 'egon', 'age': 18, 'gender': 'male'}

接下来就是想办法通过字符串来操作对象的属性了,这就涉及到4个内置函数的使用

四个内置函数(类和对象都可以被这四个函数操作)

  • hasattr() # 判断一个对象中是否有某个属性或方法(判断字符串是不是对象的属性或方法)
  • getattr() # 通过字符串获取对象中的属性或方法
  • setattr() # 通过字符串设置对象的属性或方法
  • delattr() # 通过字符串删除对象的属性或方法
class Teacher:
    def __init__(self,full_name):
        self.full_name =full_name

t=Teacher('Egon Lin')

# hasattr(object,属性)
hasattr(t,'full_name') # 按字符串'full_name'判断有无属性t.full_name

# getattr(object, 属性, 默认值)
getattr(t,'full_name',None) # 等同于t.full_name,获取对象中的属性或方法,不存在该属性则返回默认值None
注意:获取方法是获取其内存地址,使用时注意加括号
# setattr(object, 属性, 属性值)  # x.y=v
setattr(t,'age',18) # 等同于t.age=18,设置属性或方法

# delattr(object, 属性)
delattr(t,'age') # 等同于del t.age,删除了属性或方法

setattr设置方法使用解析:

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

    def print_name(self):
        print(self.name)


p = Person('sakura', 18)


def xxx(self):
    print('xxx')
    print(self.age)

# 如果直接给对象绑定方法
# setattr(p, 'print_age', xxx) #会报错
# p.print_age()
# 给类绑定方法,绑定给对象的方法是写在类中,如果使用反射,要反射到类内部
setattr(Person,'print_age',xxx)
p.print_age()

结果:
xxx
18

反射给对象(不推荐使用)
def xxx(obj):
    print(obj.age)

setattr(p,'print_age',xxx)

p.print_age(p)

反射模块 __import__('字符串')

# 反射模块:__import__('字符串')

i = input('请输入使用哪个模块:')
# __import__('字符串')
s1 = __import__(i)
s1.test()
print(s1.name)

# 如果是带路径的模块导入

i = input('请输入使用哪个模块:')  #如 root.db.db_handler
s1 = __import__(i, fromlist=True) # 加上fromlist=True即可
s1.test()
print(s1.name)

反射模块--importlib模块

# 反射模块(py3中用的比较多,框架中)避免了带有路径的模块的导入问题,适用范围更广
import importlib
i=input('请输入您要使用的模块:')
a=importlib.import_module(i)
a.test()

反射的实际应用案例:

>>> class FtpServer:
...     def serve_forever(self):
...         while True:
...             inp=input('input your cmd>>: ').strip()
...             cmd,file=inp.split()
...             if hasattr(self,cmd): # 根据用户输入的cmd,判断对象self有无对应的方法属性
...                 func=getattr(self,cmd) # 根据字符串cmd,获取对象self对应的方法属性
...                 func(file)
...     def get(self,file):
...         print('Downloading %s...' %file)
...     def put(self,file):
...         print('Uploading %s...' %file)
... 
>>> server=FtpServer()
>>> server.serve_forever()
input your cmd>>: get a.txt
Downloading a.txt...
input your cmd>>: put a.txt
Uploading a.txt...

反射和隐藏属性的结合

# 通过反射,获取隐藏属性

class Person:
    def __init__(self, name, age, sex):
        self.age = age
        self.sex = sex
        self.__name = name

p=Person('lqz',18,'男')
# name=getattr(p,'__name') # 无法获取__name属性
name=getattr(p,'_Person__name')
print(name)

# 通过反射,设置成隐藏属性
class Person:
    def __init__(self, name, age, sex):
        self.age = age
        self.sex = sex
        self.__name = name

    def print_wife(self):
        print(self.__wife)  # 相当于self._Person__wife

p=Person('qys',18,'男')

setattr(p,'__wife','刘亦菲')
print(p.__wife)  # 能,直接找到__wife属性

setattr(p,'_Person__wife','刘亦菲')  #对对象设置了p._Person__wife='刘亦菲'
# print(p.__wife)  # 不能
p.print_wife() # 能


setattr(Person,'_Person__wife','刘亦菲')  #对类设置了Person._Person__wife='刘亦菲'

print(Person.__dict__)
print(Person._Person__wife)
p.print_wife()

结果:
刘亦菲
刘亦菲
{
    '__module__': '__main__'……, '__doc__': None, '_Person__wife': '刘亦菲'}
刘亦菲
刘亦菲

反射的好处

  1. 实现可插拔机制:可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
  2. 动态导入模块(基于反射,反射当前模块成员)

类的内置方法(面向对象的魔法方法)

Class机制内置了很多特殊的方法,都是以双下划线开头和结尾的即魔法方法,会在满足某种条件时自动触发,常用的如下:

__str__和__del__

__str__方法会在对象被打印时自动触发print功能打印的就是它的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型

>>> class People:
...     def __init__(self,name,age):
...     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值