面向对象 反射 特殊方法

Posted dalaoban

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象 反射 特殊方法相关的知识,希望对你有一定的参考价值。

发射

 

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

 

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

 

四个可以实现自省的函数

 

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

getattr()

hasattr()

setattr()

delattr()

技术分享图片
class Foo:
    f = 类的静态变量
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print(hi,%s%self.name)

obj=Foo(egon,73)

#检测是否含有某属性
print(hasattr(obj,name))
print(hasattr(obj,say_hi))

#获取属性
n=getattr(obj,name)
print(n)
func=getattr(obj,say_hi)
func()

print(getattr(obj,aaaaaaaa,不存在啊)) #报错

#设置属性
setattr(obj,sb,True)
setattr(obj,show_name,lambda self:self.name+sb)
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,age)
delattr(obj,show_name)
delattr(obj,show_name111)#不存在,则报错

print(obj.__dict__)
对实例化对象示例
技术分享图片
class Foo(object):
 
    staticField = "old boy"
 
    def __init__(self):
        self.name = wupeiqi
 
    def func(self):
        return func
 
    @staticmethod
    def bar():
        return bar
 
print getattr(Foo, staticField)
print getattr(Foo, func)
print getattr(Foo, bar)
对类的示例
技术分享图片
import sys


def s1():
    print s1


def s2():
    print s2


this_module = sys.modules[__name__]

hasattr(this_module, s1)
getattr(this_module, s2)
对当前模块的示例
技术分享图片
#一个模块中的代码
def test():
    print(from the test)
"""
程序目录:
    module_test.py
    index.py
 
当前文件:
    index.py
"""
# 另一个模块中的代码
import module_test as obj

#obj.test()

print(hasattr(obj,test))

getattr(obj,test)()
其他模块的示例

 

isinstance(obj,A)   判断obj是否是A类实例化的,或者此类的派生类实例化来的

issubclass(B,A)   判断B是都为A 的派生类

技术分享图片
class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __len__(self):
        return len(self.__dict__)
a = A()
print(len(a))
len() 触发 __len__
技术分享图片
class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __hash__(self):
        return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))
hash() 触发 __hash__
技术分享图片
class A:
    def __init__(self):
        pass
    def __str__(self):
        return 太白
a = A()
print(a)
print(%s % a)
str print 触发 __str__
技术分享图片
class A:
    def __init__(self):
        pass
    def __repr__(self):
        return 太白
a = A()
print(repr(a))
print(%r%a)
repr() 触发 __repr__

???        __call__

 

对象后面加括号,触发执行。

 

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

 

 

技术分享图片
class Foo:

    def __init__(self):
        pass
    
    def __call__(self, *args, **kwargs):

        print(__call__)


obj = Foo() # 执行 __init__
obj()       # 执行 __call__
对象() 自动触发__call__

 

技术分享图片
class A:
    def __init__(self):
        self.a = 1
        self.b = 2

    def __eq__(self,obj):
        if  self.a == obj.a and self.b == obj.b:
            return True
a = A()
b = A()
print(a == b)
__eq__

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

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

※ python中的垃圾回收机制,文件中创建的所有变量,类 等,执行完后,一段使劲内如果没有用到,他会自动在内存中清除掉.

深入研究:它会将你的所有变量,类等做个标记,在一段时间内没 被调用的话,则自动回收

???__new__

类名()--->>自动执行类中的__new__方法,若类中没有,则找到object父类.

    若类中有__new__,则会执行,

 

技术分享图片
class A:
    def __init__(self):
        self.x = 1
        print(in init function)
    def __new__(cls, *args, **kwargs):
        print(in new function)
        return object.__new__(A, *args, **kwargs)

a = A()
print(a.x)
__new__
技术分享图片
class A:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            obj = object.__new__(cls)
            cls.__instance = obj
        return cls.__instance
单例模式

单例模式很重要,面试必备

???item

 

技术分享图片
class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print(del obj[key]时,我执行)
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print(del obj.key时,我执行)
        self.__dict__.pop(item)

f1=Foo(sb)
f1[age]=18
f1[age1]=19
del f1.age1
del f1[age]
f1[name]=alex
print(f1.__dict__)
item

 

f["name"] 自动触发 __getitem__方法,将"name"传入方法中

f["name"]="hah" 自动触发 __setitem__(self,key,value)

 

del f["name"] 自动触发__delitem__(self,key)

del f.name 自动触发 __delattr__(self,key)

 

以上是关于面向对象 反射 特殊方法的主要内容,如果未能解决你的问题,请参考以下文章

python 面向对象专题:元类type反射函数与类的区别特殊的双下方法

面向对象中特殊方法的补充isinstance/issubclass/type方法和函数反射

python面向对象高级:反射魔法方法元类

Python----面向对象异常处理反射单例模式

Day5—面向对象

面向对象