首页 > 编程语言 > 详细

【Python基础】类的双下划线(__xxx__)内置方法

时间:2019-05-18 21:27:36      阅读:115      评论:0      收藏:0      [点我收藏+]

类的双下划线(__xxx__)内置方法

面向对象进阶阅读目录:

反射(hasattr  getattr  setattr  delattr)

1 什么是反射

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

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

四个可以实现自省的函数:

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

技术分享图片
判断object中有没有一个name字符串对应的方法或属性
判断object中有没有一个name字符串对应的方法或属性
技术分享图片
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
getattr(object, name, default=None) #获取对象属性
技术分享图片
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

setattr(x, y, v)
setattr(x, y, v) #设置对象属性
技术分享图片
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
delattr(x, y) #删除对象属性
技术分享图片
class BlackMedium:
    feture=Ugly
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr

    def sell_hourse(self):
        print(【%s】 正在卖房子,傻逼才买呢 %self.name)

    def rent_hourse(self):
        print(【%s】 正在租房子,傻逼才租呢 % self.name)

#
b1=BlackMedium(万成置地,天露园)
# print(b1.name)   #<===> b1.__dic__[‘name‘]
print(b1.__dict__)

"""setattr 判断是否有属性"""
# # b1.name
# # b1.sell_hourse
# print(hasattr(BlackMedium,‘feture‘))        #有对应的数据属性feture,返回True
# print(hasattr(BlackMedium,‘sdfasf‘))        #没有对应的方法或属性 返回False
# print(hasattr(b1,‘name‘))       #True
# print(hasattr(b1,‘sell_hourse‘))        #True
# print(hasattr(b1,‘selasdfasdfsadfasdfasdfasdfasdl_hourse‘))     #False

"""setattr 获取属性"""
# print(getattr(b1,‘name‘))       #万成置地
# print(getattr(b1,‘rent_hourse‘))        #<bound method BlackMedium.rent_hourse of <__main__.BlackMedium object at 0x000001CDFB8C9710>>
# func=getattr(b1,‘rent_hourse‘)
# func()      #【万成置地】 正在租房子,傻逼才租呢

# print(getattr(b1,‘rent_hourseasdfsa‘))        #没有则报错
# print(getattr(b1,‘rent_hourseasdfsa‘,‘没有这个属性‘))     #没有则返回设置的默认值:没有这个属性

"""setattr 设置属性"""
# b1.sb=True
# print(b1.__dict__)      #{‘name‘: ‘万成置地‘, ‘addr‘: ‘天露园‘, ‘sb‘: True}

setattr(b1,sb,True)
setattr(b1,sb1,123)
setattr(b1,name,SB)     #有则改 没有则加
setattr(b1,func,lambda x:x+1)
setattr(b1,func1,lambda self:self.name+sb)
print(b1.__dict__)
print(b1.func)
print(b1.func(10))
print(b1.func1(b1))

"""delattr 删除属性"""
# del b1.sb
# del b1.sb1
delattr(b1,sb)
delattr(b1,func)
print(b1.__dict__)
4个方法的使用演练
技术分享图片
class Foo(object):
    staticField = "old boy"
    def __init__(self):
        self.name = wupeiqi

    def func(self):
        print("from the func()...")
        return func

    @staticmethod
    def bar():
        return bar


print(getattr(Foo, staticField))

print(getattr(Foo, func))
getattr(Foo, func)(1)     # from the func()...

print(getattr(Foo, bar))
类也是对象
技术分享图片
"""反射当前模块成员"""
import sys

def s1():
    print(s1)

def s2():
    print(s2)

this_module = sys.modules[__name__]     #A way to get a handle to the current running module in Python,即得到当前运行文件及路径

print(this_module)
print(__name__)

print(hasattr(this_module, s1))       #True
getattr(this_module, s2)()        #s2
反射当前模块成员

导入其他模块,利用反射查找该模块是否存在某个方法

技术分享图片
def test():
    print(from module_test.py the test())
module_test.py
技术分享图片
import module_test as obj

#obj.test()

print(hasattr(obj,test))      #True

getattr(obj,test)()
index.py
 """
 程序目录:
    module_test.py
     index.py
  
当前运行文件:
     index.py
 """

为什么用反射之反射的好处?

好处一:实现可插拔机制

有俩程序员,一个Alex,一个是egon,Alex在写程序的时候需要用到egon所写的类,但是egon去跟女朋友度蜜月去了,还没有完成他写的类,Alex想到了反射,使用了反射机制Alex可以继续完成自己的代码,等egon度蜜月回来后再继续完成类的定义并且去实现Alex想要的功能。总之反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

技术分享图片
class FtpClient:
    ftp客户端,但是还么有实现具体的功能
    def __init__(self,addr):
        print(正在连接服务器[%s] %addr)
        self.addr=addr
egon还没有实现全部功能
技术分享图片
#from module import FtpClient
f1=FtpClient(192.168.1.1)
if hasattr(f1,get):
    func_get=getattr(f1,get)
    func_get()
else:
    print(---->不存在此方法)
    print(处理其他的逻辑)
不影响Alex的代码编写

好处二:动态导入模块(基于反射当前模块成员)

技术分享图片

 

举例:

技术分享图片  技术分享图片

import importlib

mt = importlib.import_module(fanse_module.module_test)
mt.test()       #from module_test.py the test()

 

__setattr__,  __delattr__,  __getattr__

 

【Python基础】类的双下划线(__xxx__)内置方法

原文:https://www.cnblogs.com/XJT2018/p/10887099.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!