python getattr_来一点Python面向对象第一级进阶的东西

isinstance和issubclass

# isinstance(obj,cls) 检查obj是否是类cls的对象class Foo:    def __init__(self,name):        self.name = nameclass Clss:    def __init__(self,name):        self.name = namesb = Foo('ssb')print(isinstance(sb, Foo))  # 判断sb是否是Foo的对象sc = Clss('ak')print(isinstance(sc, Foo))  # 判断sc是否是Foo的对象# 返回值# True# False
# issubclass(sub, super)检查sub类是否是super的派生类class Foo:    def __init__(self):        passclass Sb(Foo):    def __init__(self):        passprint(issubclass(Sb, Foo))  # 判断Sb是否是Foo的子类# 结果# True

反射

反射定义:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

  python面向对象中的反射:通过字符串的形式操作对象相关属性.python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

下列方法适用类和对象(一切皆对象,类本身也是一个对象)

hasattr

def hasattr(*args, **kwargs): # real signature unknown    """    Return whether the object has an attribute with the given name.        This is done by calling getattr(obj, name) and catching AttributeError.    """    pass

getattr

def getattr(object, name, default=None): # known special case of getattr    """    getattr(object, name[, default]) -> value        Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.    When a default argument is given, it is returned when the attribute doesn't    exist; without it, an exception is raised in that case.    """    pass

setattr

def setattr(x, y, v): # real signature unknown; restored from __doc__    """    Sets the named attribute on the given object to the specified value.        setattr(x, 'y', v) is equivalent to ``x.y = v''    """    pass

delattr

def delattr(x, y): # real signature unknown; restored from __doc__    """    Deletes the named attribute from the given object.        delattr(x, 'y') is equivalent to ``del x.y''    """    pass

四方法演示

1 class Foo: 2     f = 'abc'  # 类的静态变量 3     def __init__(self, name, pwd): 4         self.name = name 5         self.pwd = pwd 6     def exex(self): 7         print('hi {}'.format(self.name)) 8         return 'ssd' 9 class Ak:10     f = 'ssd'11     def __init__(self):12         pass13 sb = Foo('张飞', 38)14 ak = Ak()15 16 # hasattr检查是否含有某些属性17 18 print(hasattr(sb, 'name'))  # 检查对象sb中是否含所有name属性  属性名以字符串形式显示19 print(hasattr(ak, 'name'))  # 检查对象ak中是否含所有name属性  属性名以字符串形式显示20 # 结果21 # True22 # False23 24 # getattr获取属性  有此对象属性就输出没有就报错,可以定制报错形式,使其不报错25 26 print(getattr(sb, 'name'))  # 获取对象的属性  getattr函数 括号第一位填对象 第二位填属性27 print(getattr(sb, 'exex'))  # 获取动态属性28 print(getattr(sb,'exex')())  # 加括号可以直接调用29 # print(getattr(sb,'rr'))  # 如果没有此属性将报错30 print(getattr(sb,'rr','不存在'))  # 如果没有此属性将报错  可以定制报错形式使其不报错31 32 # setattr设置属性 原则:如果原本含有此属性便修改其属性,如果不存在此属性,便添加此属性33 34 setattr(sb, 'sb', 27)  # 为对象sb增加属性 属性名为sb 属性值为2735 print(sb.__dict__)36 # 结果 {'name': '张飞', 'pwd': 38, 'sb': 27}37 setattr(sb, 'ak117', 38)  # 为对象sb增加属性 属性名为ak117 属性值为3838 print(sb.__dict__)39 # 结果:{'name': '张飞', 'pwd': 38, 'sb': 27, 'ak117': 38}40 setattr(sb, 'ak117', 39)  # 对对象sb修改属性 将属性为ak117的属性值修改为3941 print(sb.__dict__)42 # 结果 {'name': '张飞', 'pwd': 38, 'sb': 27, 'ak117': 39}43 setattr(sb, 'show_name', lambda self: self.name+'uu')  # 为对象增加动态方法44 print(sb.show_name(sb))45 # 结果:张飞uu46 47 # delattr删除属性  有就删除没有就报错48 49 delattr(sb, 'ak117')  # 删除 对象sb的ak117属性50 print(sb.__dict__)51 # 结果{'name': '张飞', 'pwd': 38, 'sb': 27, 'show_name':  at 0x002DC660>}52 # delattr(sb, 'rrr')  # 如果不存在此属性将会报错53 # print(sb.__dict__)四方法演示

类也是对象

class Foo:    name = '38'    def func():        return 'AK117'    @staticmethod    def funct():        return 'funct'print(getattr(Foo, 'name'))print(getattr(Foo, 'func')())print(Foo, 'funct')

反射当前模块成员

import sysdef s1():    print('s1')def s2():    print('s2')this_module = sys.modules[__name__]print(hasattr(this_module, 's1'))print(getattr(this_module, 's2'))

__str__和__repr__

# 改变对象的字符串显示__str__,__repr__

# 自定制格式化字符串__format__

__str__ 使用方法及含义

# __str__ 使用方法及含义class Human:    def __init__(self, name):        self.name = name  # 2试验    def __str__(self):        # return '我是str方法,打印对象时调用的就是我,我是存在于object类中'  # 1试验        return 'my name is %s' % self.name  # 2试验  解释  %s相当于str() 实际上走的是__str__方法# a = Human()  # 1试验# print(a)  # 1试验# 结果:我是str方法,打印对象时调用的就是我,我是存在于object类中  # 1试验a = Human('明明')  # 2试验print(a)  # 2试验# 结果  my name is 明明  # 2试验

__repr__使用方法及含义

# __repr__使用方法及含义class Hunman:    def __init__(self, name, age):        self.name = name        self.age = age    def __repr__(self):        return str(self.__dict__)a = Hunman('Mr.He','Twenty-two')print(repr(a))  # 同理repr函数也是调用内置方法  __repr__print('>>>%r'% a)  # %r 相当于 repr() 或者  __repr__# 结果# {'name': 'Mr.He', 'age': 'Twenty-two'}# >>>{'name': 'Mr.He', 'age': 'Twenty-two'}# 如果不使用__repr__方法,则返回内存地址

__str__ and __repr__关系

# __str__ and __repr__ relationshipclass Human:    def __repr__(self):        return str(12345)a = Human()print('%s' % a)# 结果:12345# 原本%s 相当于 __str__方法,但类中无此方法,正常情况下是该报错的。# 但可以正常输出结果-----》结论:__repr__是__str__的备胎。# 如果类中无__str__便去查看父类是否含有,一个父类一个父类找上去直到找到object类中。# 如果没有便找__repr__代替

__len__

# __len__方法class A:    def __init__(self):        self.a = 1        self.b = 2    # def __len__(self):    #     return  len(self.__dict__)s = A()print(len(s))  # 直接调用了类中的__len__方法# 注意  有些方法在object类中是没有被收录的。# 故如果不构建__len__方法,来读取一个int类型的数据的长度便会报错# 错误类型为:TypeError: object of type 'A' has no len()

__del__(析构函数)

析构方法,当对象在内存中被释放时,自动触发执行。

  注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

# __del__class Currency:    def __del__(self):        print('执行了我,删除了你要删除的数据')a = Currency()del a  # 即执行了这个方法,又删除了变量

__call__

# __call__class Human:    def __init__(self, name):        self.name = name    def __call__(self, *args, **kwargs):        '''此处可以写一些小方法'''        print('abc')a = Human('Mr.he')a()# 结果:abc

#Python##Python 语言##Python入门推荐##面向对象程序编程##科技新星创作营#

33533231c3d5463db662644f3c5a2e4c
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值