Example: object constructor specifies type passed in parameters (Application of descriptor and decorator)

In python, the incoming parameters are not like c + +, java, which has strict type checking. You can pass different types of parameters to a variable. Such as parameter name, string, integer and floating-point arguments can be passed; how to improve it?

 1 class Typed:
 2     def __init__(self,key,type_var):
 3         self.type_var=type_var
 4         self.key=key
 5     def __get__(self, instance, owner):
 6         print('get------>',instance)
 7         print('get------>', owner)
 8         return instance.__dict__[self.key]
 9     def __set__(self, instance, value):
10         print('set------>',instance)
11         print('set------>', value)
12         if not isinstance(value,self.type_var):
13             raise TypeError('What you entered%s No%s type'%(self.key,self.type_var))
14         else:
15             instance.__dict__[self.key]=value
16 class People:
17     name=Typed('name',str)
18     age=Typed('age',int)
19     salary=Typed('salary',int)
20     def __init__(self,name,age,salary):
21         self.name=name
22         self.age=age
23         self.salary=salary
24 p=People(12,18,22014)
25 ----------output
26     raise TypeError('What you entered%s No%s type'%(self.key,self.type_var))
27 TypeError: What you entered name No<class 'str'>type

Similarly, when the input name is not str, age is not int, and salary is not int, an error will be reported. The name, age, and salay in People are all descriptor proxy properties. When executing 21, 22, 23 lines of code, of course, the set setting method in the descriptor will be triggered only after the object is instantiated. Pictured output

1 #p=People(12,18,22014)
2 p1=People('alex',18,2201)
3 -----------output
4 set------> <__main__.People object at 0x00000253C8E8B438>
5 set------> alex
6 set------> <__main__.People object at 0x00000253C8E8B438>
7 set------> 18
8 set------> <__main__.People object at 0x00000253C8E8B438>
9 set------> 2201

Note that the constructor of the descriptor class, init, has the key and typ var attributes set in advance. It is used to trigger the set and get operations of descriptor object name and age when passing parameters. However, it seems that it is not easy. If you want to pass in strict requirements for a specified parameter, you must have the attribute = Typed ('attribute ', attribute type). If you want the name to be str type, you must have the name=Typed ('name', str). If you want to set multiple, there will be many redundant codes. Next, use decorators to improve -------------

 1 class Typed:
 2     def __init__(self,key,type_var):
 3         self.type_var=type_var
 4         self.key=key
 5     def __get__(self, instance, owner):
 6         print('get------>',instance)
 7         print('get------>', owner)
 8         return instance.__dict__[self.key]
 9     def __set__(self, instance, value):
10         print('set------>',instance)
11         print('set------>', value)
12         if not isinstance(value,self.type_var):
13             raise TypeError('What you entered%s No%s type'%(self.key,self.type_var))
14         else:
15             instance.__dict__[self.key]=value
16 def foo(**kwargs):
17     def wrapper(obj):
18         for key,value in kwargs.items():
19             print('----',key,value)
20             setattr(obj,key,Typed(key,value))#People.name=Typed('name',str)
21         return obj
22     return wrapper
23 @foo(name=str,age=int,salary=int)#@wrapper---->People=wrapper(People)
24 class People:
25     # name=Typed('name',str)
26     # age=Typed('age',int)
27     # salary=Typed('salary',int)
28     def __init__(self,name,age,salary):
29         self.name=name
30         self.age=age
31         self.salary=salary
32 p=People(12,18,22014)
33 print(p.__dict__)
 ------>>>>>>raise TypeError('What you entered%s No%s type'%(self.key,self.type_var))
TypeError: What you entered name No<class 'str'>type

 

 1 # p=People(12,18,22014)
 2 # print(p.__dict__)
 3 p1=People('alex',18,2201)
 4 print(p1.__dict__)
 5 --------->>
 6 ---- name <class 'str'>
 7 ---- age <class 'int'>
 8 ---- salary <class 'int'>
 9 set------> <__main__.People object at 0x00000161D311B400>
10 set------> alex
11 set------> <__main__.People object at 0x00000161D311B400>
12 set------> 18
13 set------> <__main__.People object at 0x00000161D311B400>
14 set------> 2201
15 {'name': 'alex', 'age': 18, 'salary': 2201}

At this time, you can add attributes according to them, and write the variables and types you want to transfer without any duplication of code, which will be stored in the dictionary of the decorator for further unified processing

Tags: Python Attribute Java

Posted on Tue, 03 Dec 2019 09:10:29 -0500 by rohithreddyk