Python 类的魔术方法的初步使用

issubclass 和 ininstance

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

class Foo(object):
	pass
obj = Foo()  
isinstance(obj, Foo)

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

class Foo(object):
	pass  
class Bar(Foo):
	pass
issubclass(Bar, Foo)

反射

什么是反射:

主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

  • hasattr(object,name)判断一个属性是否在对象中,返回True或者False
  • getattr(object, name, default=None)通过字符串获取属性或方法,如果获取到了,就会返回相应的属性或方法
  • setattr(x, y, v) 通过字符串来设置属性或方法
  • delattr(x, y) 通过字符串来删除属性或方法

hasattr(object,name)判断一个属性是否在对象中,返回True或者False

class Foo:
    name = 'guapi'
    def __init__(self):
        pass
    def run(self):
        a = 10
        print('aaaa')
        return a
def test():
    print('nihao')

#print(hasattr(x,x.name))   False
#print(hasattr(x,'name'))   Ture
#print(hasattr(Foo,Foo.name))    False
#print(hasattr(Foo,'name'))  False
#print(hasattr(Foo,'Foo'))  False
#print(hasattr(Foo,Foo))     TypeError: hasattr(): attribute name must be string

getattr(object, name, default=None)通过字符串获取属性或方法,如果获取到了,就会返回相应的属性或方法

class Foo:
    name = 'guapi'
    def __init__(self):
        pass
    def run(self):
        a = 10
        print('aaaa')
        return a
def test():
    print('nihao')

#getattr(x,x.run)() TypeError: getattr(): attribute name must be string
#getattr(x,'run')()  aaaa
#print(getattr(x,'name'))    guapi
#getattr(x,'x.run')()    AttributeError: 'Foo' object has no attribute 'x.run'
#getattr(x,'Foo.run')()  AttributeError: 'Foo' object has no attribute 'Foo.run'

setattr(x, y, v) 通过字符串来设置属性或方法

class Foo:
    name = 'guapi'
    def __init__(self):
        pass
    def run(self):
        a = 10
        print('aaaa')
        return a
def test():
    print('nihao')

#print(x.__dict__)   #{}
#setattr(x,'test',test)
#print(x.__dict__)   #{'test': <function test at 0x0000025FC819F4C8>}
#print(x.test())     nihao
                    #None
#setattr(x.run(),'a',20)
#print(x.run())AttributeError: 'int'对象没有属性'a'
#print(x.run())   run() missing 1 required positional argument: 'a'(缺少关键字a)
#print(x.run())  TypeError: setattr() takes no keyword arguments(不接受关键字参数)
#setattr(x,'x.run',print('bbb')) bbb 不可用
#print(x.run())  TypeError: 'NoneType' object is not callable(不可调用)
#setattr(x,'age',18)
#print(x.age)

delattr(x, y) 通过字符串来删除属性或方法

class Foo:
    name = 'guapi'
    def __init__(self):
        pass
    def run(self):
        a = 10
        print('aaaa')
        return a
def test():
    print('nihao')

x = Foo()
print(Foo.__dict__)     #{'__module__': '__main__', 'name': 'guapi', '__init__': <function Foo.__init__ at 0x00000249CD1FF678>, 'run': <function Foo.run at 0x00000249CD1FF3A8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
delattr(Foo,'__init__')
print(Foo.__dict__)     #{'__module__': '__main__', 'name': 'guapi', 'run': <function Foo.run at 0x00000249CD1FF3A8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
delattr(Foo,'name')
print(Foo.__dict__)     #{'__module__': '__main__', 'run': <function Foo.run at 0x000002C674A5F3A8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}

内置方法(魔法方法)

_str_

    #print(__str__)  #不重写打印内存地址

#f = Foo('guapi')
#print(f.__str__) <bound method Foo.__str__ of <__main__.Foo object at 0x00000205DC4C5BC8>>
#print(f.__str__())  None
#print(f.__str__())

重点:

  • __setattr__如果去对象中取属性,一旦取不到,会进入到_getattr_

  • _delattr__如果去对象中赋值属性,一旦取不到,会进入到__setattr_

  • _getattr__如果删除对象中的属性,会进入__delattr_

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

    def __getattr__(self, item):
        return '傻逼'
    #def __setattr__(self, key, value):
        #print('改不了滚蛋')
    def __delattr__(self, item):
        print('想屁吃呢?')
f = Foo('guapi')
#f.age = 18
#Foo.name = 'guapi'
#print(Foo.name)
#print(f.__dict__) {}
#print(f.age) 傻逼
del f.name
print(f.__dict__)
原文地址:https://www.cnblogs.com/ledgua/p/11449369.html