-2

I have create a sample function where I want to pass all the keys in dict third_party to eval statement. Using itemgetter is not possible as dictionary key are variable.

def sample(third_party):
    '''
    :param third_party: is a dictionary number of keys and exact keys name varies
    '''
    #Types can be of multiple type, using if/else not possible
    #type will always a key
    tp_type = third_party['type']
    if tp_type[-1] == 's':
        type_execution = tp_type + '_s'
    else:
        type_execution = tp_type + 's'
    #How to destructure dictionary into eval command as function arguments
    eval_statement = "inital.constant.command" + type_execution +  ".create("**third_party")"
    eval(eval_statement)
1
  • 1
    dont' use eval here. eval_statement = "inital.constant.command" + type_execution + ".create("**third_party")" Use getattr. Commented Sep 14, 2021 at 4:53

1 Answer 1

2

Short answer: there's no syntactical sugar for what you're trying to do, as far as I'm aware.

Here's one way you can achieve your desired result though:

args = ", ".join(f"{k}={v}" for k, v in third_party.items())
eval_statement = f"inital.constant.command{type_execution}.create({args})"

That said, it's not really clear why you need to use eval(). Note that using eval() is generally considered bad practice so I strongly recommend reconsidering your approach to this problem.

For instance, if third_party["type"] returns the actual name of an attribute of the initial.constant object, whatever it is, you could simply do

exec_type = third_party["type"]
func = getattr(initial.constant, f"command{exec_type}")
func.create(**third_party)

Here's a simple demo:

In [1]: class A:
   ...:     def f(self, x):
   ...:         return x**2
   ...:
   ...:     def g(self, x):
   ...:         return x**3
   ...:

In [2]: a = A()

In [3]: getattr(a, "f")
Out[3]: <bound method A.f of <__main__.A object at 0x0000019A291D3790>>

In [4]: f = getattr(a, "f")

In [5]: f(3)
Out[5]: 9

But without knowing what your data look like, and what the objects you're working with look like I can't say for sure.

Sign up to request clarification or add additional context in comments.

6 Comments

Having all methods store in dictionary is better than if/else. But these type are around 50. Want to know if some thing better exists.
Yeah, I mean assuming you have a limited number of methods, it's vastly more superior than needing to use eval().
Aye, that downvote was me. The eval just shows the user how to shoot themselves in the foot. Building dictionary is not helpful in the case the <???> are unknown ahead of time (or there are very many of them), i.e. that is not a truly dynamic solution. The obvious dynamic approach that your answer is missing is using getattr for the "type_execution". But actually, I don't think this question should be answered at all (yet) because it has a syntax error and isn't clear.
It's clear that third_party['type'] is string (since it's added to another string) and that's the one that matters, the usage would be like getattr(inital.constant, "command" + type_execution). .... annnnd you deleted the comment that I was replying to :)
But it's also clear that the values that third_party["type"] takes on don't necessarily correspond 1:1 with an attribute, since OP is adding _s in some cases. Either way, I've added exactly what you're talking about in my latest edit.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.