Есть ли способ использовать строку имен переменных в качестве входных данных для функции? - PullRequest
0 голосов
/ 27 мая 2020

Я хотел бы знать, возможно ли что-то подобное (Python код ниже)

def my_function(v1, v2):
    return v1+v2

var1 = 1
var2 = 2

vars = "var1,var2"

print(my_function(vars))

Я знаю, что этот код не будет работать, потому что функция требует двух аргументов, но причина, по которой я хотел бы знать, что я хотел бы разработать функцию, которая может изменять длину аргумента. * args и ** kwargs не будут работать, потому что функция, которую я вызываю, уже сгенерирована. Вот фрагмент моего кода для контекста

def construct_transaction(value, chain_id, gas, gas_price, **params):

    # amountIn = w3.toWei(0.1, 'ether')   # << These are the variables I would like to 
    # amountOutMin = 1                    # input into the function below
    # path = [token_0_addr, token_1_addr] # "swapExactTokensForTokens"
    # to_addr = my_addr
    # deadline = 1690528847

    for key in params.keys():
        locals()[key] = params[key]       # variables created from params

    nonce = w3.eth.getTransactionCount(w3.toChecksumAddress(my_addr))

    txn = uniswap_v2_router_contract.functions.swapExactTokensForTokens("amountIn,..,"). \
        buildTransaction({
        'value': 0,
        'chainId': chain_id,
        'gas': gas,
        'gasPrice': gas_price,
        'nonce': nonce,
    })

количество аргументов будет меняться в зависимости от контракта и вызываемой функции. Заранее спасибо.

1 Ответ

0 голосов
/ 27 мая 2020

Вы можете сохранить свои функции в dict для доступа к ним по имени, а затем передать аргументы как *args:

def execute_fun(my_funs: dict, name: str, args: tuple):
    """
    lookup a function by name from my_funs dict and execute it using the provided args
    """
    return my_funs[name](*args)

def first_fun(a):
    return a + a

def second_fun(a, b):
    return a + b

my_funs = {
    'first_fun': first_fun,
    'second_fun': second_fun
}

execute_fun(my_funs, 'first_fun', (7,)) # 14
execute_fun(my_funs, 'second_fun', (4, 5,)) # 9

Это выглядит как будто Однако лучше использовать классы, потому что он поместит все в правильное пространство имен:

class A:

  def first(self, a):
        return a + a

    def second(self, a, b):
        return a + b

    def __getitem__(self, name):
        return getattr(self, name)

    def __call__(self, name, args):
        return self[name](*args)

a = A()
a['first'] # <bound method A.first of <__main__.A object at 0x7fe934541790>>
a('first', (7,)) # 14
a('second', (4, 5,)) # 9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...