The reflection mechanism is implemented by Python3 built-in hasattr, GetAttr, and SetAttr. The property or method that gets the variable name based on the string form of the variable name.
I. Viewing properties and methods of known objects through reflection
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's returned when the attribute doesn ' t exist; Without it, an exception was raised in the case.
GetAttr receives three parameters: an object, a property or method of an object, and a default return value when it is not acquired.
classMyClass (object): Country=" China" def __init__(self, Name, age): Self.name=name Self.age=Age Self._gender=NonedefHello (self):Print("I ' m {}, {}.". Format (Self.name, self.age))defGender (self, gender): Self._gender=GenderPrint(Self._gender)Print(GetAttr (MyClass,"Country"))#get the static properties of an objectmy = MyClass ("Li", 24)Print(GetAttr (My,"name"))#Gets the variable (property) of the instanceGetAttr (My,"Hello")()#methods to get and execute an instanceGetAttr (My,"Gender")("female")#Incoming Parameters
Second, the method of obtaining the module through Reflection 1. Access the object of the current module.
deffunc (): Func.name="Li"Func.age= 24Print("I ' m {}, {}.". Format (Func.name, func.age))if __name__=='__main__': ImportSYS#need to introduce the SYS module to access the memory address of the current module with sys.modelus["__main__"GetAttr (sys.modules["__main__"],"func")()#getting properties from a module Print(GetAttr (func,"name"))
2. Access the objects of other modules.
Save the above code in the test1.py file, import the test1.py in test2.py, and also access the MyClass class.
Importtest1if __name__=='__main__': MyClass= GetAttr (Test1,"MyClass")#You can also use sys.modules["test1" to replace Test1 . Print(myclass.country) My= MyClass ("Li", 24) Print(GetAttr (My,"name"))#Gets the variable (property) of the instanceGetAttr (My,"Hello")()#methods to get and execute an instanceGetAttr (My,"Gender")("female")#Incoming Parameters
Iii. __import__ and Importlib.import_module
Python3 provides a special method: __import__ (String argument). The __import__ () method dynamically imports a module of the same name according to the parameters. Its function and getattr are similar.
The same functionality can be achieved by changing the code in test2.py to the following two lines.
__import__ ("test1""func") ()
or write this:
Import= Importlib.import_module ("test1"" func ") ()
They all access the memory space of the module according to the module name, thereby acquiring objects such as global variables, functions, or classes.
Take a look at the documentation:
It is better to use Importlib.import_module () to programmatically import a module.
# The Import module should be used with Importlib.import_module (), __import__ is provided to the Python interpreter.
# globals and locals, level parameters can be ignored.
The fromlist should is a list of names to emulate "from name import ...", or an empty list to emulate ' import name '. When the importing a module from the a package, note that __import__ (' a.b ', ...) returns package A when FromList was empty, but it S submodule B when fromlist are not empty.
# FromList is a list of names BlaBla. But tried a few times, as if only with true to set, others do not use
module =__import__("test1", )#it is equivalent to import test1#module = __import__ ("Test.person", Fromlist=true) # It is equivalent to the From test import person#Import the Py file from the module, test is a package containing __init__.py and person.py#person.py contains the MyClass classMyclass = GetAttr (module,"MyClass") My= Myclass ("Li", 24) My.hello ()
The use of importlib is similar.
Importimportlib#module = importlib.import_module ("test1") # import Test1#module = importlib.import_module ("Test.person", Package=true) # from test import personmodule = Importlib.import_module ("Test_outer.test.person", package=true)#From test_outer.test import personMyclass = GetAttr (module,"MyClass") My= Myclass ("Li", 24) My.hello ()
Iv. Example 1. Traverse the module to find the desired function.
# folder Test __init__ . PY -drink.py # defines a drink function that prints "I ' m drinking." - person.py -say.py # with drink.py -sleep.py # With drink.py
person.py
ImportOSImportimportlibclassPerson :def __init__(self, name): Self.name=name Self.modules=self.py_list ()defpy_list (self): Pys= Os.listdir (Os.path.dirname (__file__)) Modules= [] forPyinchPys:ifPy.endswith (". PY") and notPy.startswith ("__"): Modules.append (Importlib.import_module (Py.split (".") [0]) # import multiple modules into a listreturnModulesdefAction (self): whileTrue:imp= Input ("Xiao Ming >>>") Fun=None forModuleinchself.modules: # Traverse query module, find Imp functionifhasattr (module, IMP): Fun=getattr (module, IMP) Break ifFun:fun ()Else: Print("Order isn ' t correct.")if __name__=='__main__': Per= Person ("Li") per.action ()
2. Dynamic Import Module
Of course, depending on the module name and object name, you can also get the corresponding module and call the appropriate method. So you don't have to import all of the modules in.
ImportimportlibclassPerson :def __init__(self, name): Self.name=namedefAction (self): whileTrue:imp= Input ("Xiao Ming >>>") Try: module, fun= Imp.split ("/") Module=importlib.import_module (module,)ifhasattr (module, fun): GetAttr (module, Fun) ()Else: Print("Order isn ' t correct.") except: Print("input not correct.")if __name__=='__main__': Per= Person ("Li") per.action ()#need to enter Sleep/sleep or Drink/drink
Use of 3.setattr
ImportimportlibclassPerson :def __init__(self, name): Self.name=namedefSleep (self): GetAttr (Importlib.import_module ("Sleep"),"Sleep")() defDrink (self): GetAttr (Importlib.import_module ("Drink"),"Drink")() defFun (Self, Action):ifhasattr (Self, Action): GetAttr (Self, Action)Else: SetAttr (Self, Action, Self.error) # Sets the function of Aciton, of course, can be set in the default keyword of getattr above getattr (self, a ction) () # function called Actiondeferror (self):Print("error.")if __name__=='__main__': Per= Person ("Li") Per.fun ("wth")
Python (eight): Reflection