简体   繁体   中英

Python: Dynamic classmethod creation from dictionary

I am trying to find a way to dynamically create class methods from a dictionary (I tried to adapt the answer from this post ).

# define a class object (your class may be more complicated than this...)  
class TargetClass(object):
    pass

class ReturnClass():
    def __init__(self, *args, name_of_calling_function):
       pass

    
#ref_dict = {attribute_name : {**kwargs}}
ref_dict = {'pfly' : {'ratio' : [1, -2, 1], 'opt_types' : ['c']*3},
               'rfly' : {'ratio' : [1, -2, 1], 'opt_types' : ['p']*3},
               'ps' : {'ratio' : [1, -1], 'opt_types' : ['c']*2},
               'rs' : {'ratio' : [1, -1], 'opt_types' : ['p']*2},
               'rr' : {'ratio' : [1, -1], 'opt_types' : ['c', 'p']},
               'strg' : {'ratio' : [1, 1], 'opt_types' : ['c','p']},

# a class method takes the class object as its first variable
# how do associate 1 function to each dictionary key?
def func(cls, *user_args):
    print 'I am a class method'
    return ReturnClass(*user_args, name_of_calling_function = ??)  # I could even simply pass in the name of the function, to lookup in ref_dict later

# or you can auto-generate the name and set it this way
the_name = 'other_func' 
for key_as_the_name in ref_dict.keys():
    setattr(A, key_as_the_name, classmethod(func)) # but its not just 1 function, its a list of functions no?

In my case though, I want 1 func for every dictionary key. Desired outcome is that the following all work:

TargetClass.pfly(args) -> ReturnClass
TargetClass.rfly(args) -> ReturnClass
TargetClass.ps(args) -> ReturnClass
TargetClass.rs(args) -> ReturnClass
TargetClass.rr(args) -> ReturnClass
TargetClass.strg(args) -> ReturnClass

You can define the function inside the loop with each name assigned as the value of a default parameter:

for name in ref_dict:
    def func(cls, *user_args, name=name):
        print(f"I am a class method of '{cls}' named '{name}'")
        return ReturnClass(*user_args)
    setattr(TargetClass, name, classmethod(func))

so that:

print(TargetClass.rfly('foo', 'bar'))
print(TargetClass.ps('foo', 'bar'))

outputs:

I am a class method of '<class '__main__.TargetClass'>' named 'rfly'
<__main__.ReturnClass object at 0x00000183939BC990>
I am a class method of '<class '__main__.TargetClass'>' named 'ps'
<__main__.ReturnClass object at 0x00000183939BC9D0>

Demo: https://replit.com/@blhsing/ToughPlasticFunctions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM