python中getattr详解

一.消除if…else

因为代码中涉及到太多的if…else. 本来想使用策略模式 + 工厂模式 (消除if…else). 但是由于项目起始没有考虑代码设计模式, 导致现在改动会花费增加很大的工作量. 所以只能想其他的办法.

  • 之前对jumpserver 进行二次开发时, 研究过核心代码. 发现代码中使用了大量的getattr, 里面getattr主要是用在函数调用上. 比如下面我截取部分代码

     
    def run_command(self, func_name, args):
            """ Attempts to run the given command.
     
                If the command does not execute, or there are any problems
                validating the given GET vars, an error message is set.
     
                func: the name of the function to run (e.g. __open)
                command_variables: a list of 'name':True/False tuples specifying
                which GET variables must be present or empty for this command.
            """
            if not self.check_command_args(args):
                self.response['error'] = 'Invalid arguments'
                print("++++++++++++++++++++++++++++++++ not valid")
                return
     
            func = getattr(self, '_' + self.__class__.__name__ + func_name, None)
            if not callable(func):
                self.response['error'] = 'Command failed'
                return
     
            try:
                func()
            except Exception as e:
                self.response['error'] = '%s' % e
                logger.error("Error occur ------------------------------")
                logger.exception(e)
                logger.error("Error end ------------------------------")

    getattr是python里的一个内建函数,在python的官方文档中:getattr()的解释:

    getattr(object, name[, default])

    Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, ‘foobar’) is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

    getattr()这个方法最主要的作用是实现反射机制。也就是说可以通过字符串获取方法实例。这也是python中的所说的自省这样,

    • 你就可以把一个类可能要调用的方法放在配置文件里,在需要的时候动态加载。
  • python里面跟getattr相关的有hasattr,setattr,delattr,那么我们通过下面的例子,来详细的说说他们的用法。

二. 反射机制

  1. hasattr(object,name) 

  • bool 判断object中是否具有name属性,例如:
foo = test()
 
hasattr(foo,’setName’) #判断setName是否存在,存在则返回True。

2.getattr(object,name,default)

  • 如果存在name属性(方法)则返回name的值(方法地址)否则返回default值。

# foo.py
 
def name():
    return "hello"
 
# main.py
import foo
 
getattr(foo,'name',"default value") # 存在name属性,所以返回其value
# "hello"
 
getattr(foo,'test',None)
# None
  • 这里函数的调用方式.

3.setattr(object,name,default)

  • 为类设置一个新的属性

class Foo(object):
    def __init__(self,sex):
        self.sex = sex
        
foo = Foo('man')      # 实例化类  
setattr(Foo,'age',18) # 设置一个新的属性
 
foo.age
# 18
  • 改变原有的类属性的值

class Foo(object):
    def __init__(self,sex):
        self.sex = sex
        
foo = Foo('man')           # 实例化类  
setattr(Foo,'sex','woman') # 设置一个新的属性
 
foo.sex
# woman

4.delattr(object,'name')

  • 删除类属性

delattr(foo,'sex')  #删除属性sex,原值为`woman`
 
getattr(foo,'sex','not find')
#'not find''

三.getattr 详解

本篇重点是讲述getattr的用法

1. 函数

  • demo.py
#!/usr/bin/env python
# ~*~ coding: utf-8 ~*~
 
import time
 
def hello(a, b):
    print('hello')
    return a, b
 
def test_sleep(a, b):
    print('test_sleep')
    time.sleep(3)
    return a, b
  • main.py
    #!/usr/bin/env python
    # ~*~ coding: utf-8 ~*~
     
    import multiprocessing
    import demo
     
    def run(func, *args):
        print(getattr(demo, func)(*args))
     
     
    if __name__ == "__main__":
        run('hello', "a", "b")
        pool = multiprocessing.Pool(processes=4)
     
        for i in range(10):
            pool.apply_async(run, ('hello', 'a', 'b'))
            pool.apply_async(run, ('test_sleep', 'a', 'b'))
        pool.close()
        pool.join()
     
        print("END ")

          定义一个字符串,然后用getattr去执行,这样调用效果有些类似python的celery那种用globals的用法。 传递一个函数的名字,当然是字符串,用multiprocessing多进程调用这个方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值