Reflection (and the hasattr setattr and delattr)

Reflection (and the hasattr setattr and delattr)

A reflective used in class

Is reflected by the operation attribute string class or object, reflected in the use of built-in functions essentially, wherein the reflector has four built-in functions:

  1. hasattr: By a string, a method of determining whether there is the class
  2. getattr: to obtain the memory address of the object obj in the method according to the corresponding character string, plus "()" to perform the brackets (lookup property returns the attribute value, the function returns the address lookup function)
  3. setattr: setattr the outside by a function bound to the instance (or a method to set the properties as a string)
  4. delattr: Delete a class or instance method string
class People:
    country = 'China'

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

    def eat(self):
        print('%s is eating' % self.name)


peo1 = People('randy')
print(hasattr(peo1, 'eat'))  # peo1.eat

True

# 获取对象中’'eat'函数
print(getattr(peo1, 'eat'))  # peo1.eat

<bound method People.eat of <main.People object at 0x1043b9f98>>

# 获取对象中的‘xxxxx'
print(getattr(peo1, 'xxxxx', None))

None

# setattr(f, key, value)
setattr(peo1, 'age', 18)  # peo1.age=18
print(peo1.age)

18

print(peo1.__dict__)

{‘name’: randy, ‘age’: 19}

# 删除对象中的name属性
f.name = 'randy'
print(f.__dict__)
del f.name
print(f.__dict__)

{'name': 'randy'}
{}

Second, the application

class Ftp:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    def get(self):
        print('GET function')

    def put(self):
        print('PUT function')

    def run(self):
        while True:
            choice = input('>>>: ').strip()

            if choice == 'q':
                print('break')
                break


#             print(choice, type(choice))
#             if hasattr(self, choice):
#                 method = getattr(self, choice)
#                 method()
#             else:
#                 print('输入的命令不存在')

            method = getattr(self, choice, None)

            if method is None:
                print('输入的命令不存在')
            else:
                method()

conn = Ftp('1.1.1.1', 23)
conn.run()

Third, the use of reflection in the module

# test.py
def f1():
    print('f1')


def f2():
    print('f2')


def f3():
    print('f3')


def f4():
    print('f4')


a = 1

import test as ss

ss.f1()
ss.f2()
print(ss.a)

We want to import another module, you can use the import. Now we have this demand, I enter a dynamic module name, you can access the method or variable import module at any time, how to do it?

imp = input(“请输入你想导入的模块名:”)
CC = __import__(imp) 這种方式就是通过输入字符串导入你所想导入的模块 
CC.f1()  # 执行模块中的f1方法

Above we achieve a dynamic input module name, which allows us to perform a function of the input module name and inside. But above it has a drawback that the function performed is fixed. So, we can improve the look, dynamic input function name, and to enforce it?

# dynamic.py
imp = input("请输入模块:")
dd = __import__(imp)
# 等价于import imp
inp_func = input("请输入要执行的函数:")

f = getattr(dd, inp_func,
            None)  # 作用:从导入模块中找到你需要调用的函数inp_func,然后返回一个该函数的引用.没有找到就返回None

f()  # 执行该函数

Input modules: time
enter the function to be performed: time

1560959528.6127071

We achieve the above, introducing a dynamic module, the function name and the dynamic input and performing the corresponding functions.

Of course, the above there is a little bit small problem: that is my name module may not have kept the same level in the directory. There may be storage methods below:

dd = __import__("lib.text.commons")  # 这样仅仅导入了lib模块
dd = __import__("lib.text.commons", fromlist=True)  # 改用这种方式就能导入成功
# 等价于import config
inp_func = input("请输入要执行的函数:")
f = getattr(dd, inp_func)
f()

Fourth, reflection

It says so much, in the end what is the reflection of it?

In fact, it is reflected by a string, import module; by a string, to find the specified function module, and execute. Use a string to an object (module) in operation (Find / get / delete / add) members, based on a string of driving events!

4.1 getattr()

getattr () function is a function of the core Python introspection, specific use roughly as follows:

class A:
    def __init__(self):
        self.name = 'nick'
        # self.age='18'

    def method(self):
        print("method print")


a = A()

print(getattr(a, 'name',
              'not find'))  # 如果a 对象中有属性name则打印self.name的值,否则打印'not find'
print(getattr(a, 'age',
              'not find'))  # 如果a 对象中有属性age则打印self.age的值,否则打印'not find'
print(getattr(a, 'method', 'default'))  # 如果有方法method,否则打印其地址,否则打印default
print(getattr(a, 'method', 'default')())  # 如果有方法method,运行函数并打印None否则打印default

4.2 hasattr(object, name)

Description: The object is to determine whether the object contains properties named name (hasattr by calling getattr (ojbect, name) throws an exception if implemented)

4.3 setattr(object, name, value)

This is the corresponding getattr (). Parameter is an object, a string and an arbitrary value. The string may be listed in an existing property or a new property. This function assigns a value to the property. This object allows it provides. For example, setattr (x, "foobar", 123) corresponding to x.foobar = 123.

4.4 delattr(object, name)

A set of functions related setattr (). Parameter is an object (remember python, everything is an object) and a string composed. The string argument must be one of the object property name. This function deletes a specified by the obj string attribute. delattr (x, 'foobar') = del x.foobar

We can use the above-described four functions, to perform a series of operations of the module.

r = hasattr(commons, xxx)  # 判断某个函数或者变量是否存在
print(r)

setattr(commons, 'age', 18)  # 给commons模块增加一个全局变量age = 18,创建成功返回none

setattr(commons, 'age', lambda a: a + 1)  # 给模块添加一个函数

delattr(commons, 'age')  # 删除模块中某个变量或者函数

Note: getattr, hasattr, setattr, delattr modifications to the modules are in memory and does not affect the actual file contents.

4.2 Application

Simulation web reflection based routing framework

Requirements: For example, we enter <www.xxx.com/commons/f1>, returns the result of f1.

# 动态导入模块,并执行其中函数
url = input("url: ")

target_module, target_func = url.split('/')
m = __import__('lib.' + target_module, fromlist=True)

inp = url.split("/")[-1]  # 分割url,并取出url最后一个字符串
if hasattr(m, target_func):  # 判断在commons模块中是否存在inp这个字符串
    target_func = getattr(m, target_func)  # 获取inp的引用
    target_func()  # 执行
else:
    print("404")

Guess you like

Origin www.cnblogs.com/randysun/p/11449301.html