Во-первых, я уже видел ряд подобных вопросов, хотя это был не совсем мой вопрос. Я уже знаком с * args и ** kwargs.
Вопрос Пояснение:
При вызове функции я обычно использую позиционные аргументы. Тем не менее, мне часто приходится переводить множество аргументов в функцию, поэтому использование позиционных аргументов стало довольно обременительным. Я также обнаружил, что мне нужно передать переменное количество переменных в функцию, которая может принимать больше или другие переменные, если это необходимо.
Как передать многие аргументы в функцию, которая может принимать различные аргументы?
Я попытался создать пример, максимально простой. Функции выполняют некоторые арифметические операции над некоторыми переменными, а затем распечатывают их.
a = 10
b = 20
c = 30
def firstFunction(*args):
d = a *2
e = b /2
f = c +2
x = d -10
y = e -10
z = f -10
h = 1 #or 2
secondFunction(d,e,f,h)
thirdFunction(x,y,z,h)
def secondFunction(d,e,f,h):
if h == 1:
print d
print e
print f
def thirdFunction(x,y,z,h):
if h == 2:
print x
print y
print z
firstFunction(b,c,a)
И результаты, полученные, как и ожидалось, для h = 1 и h = 2 соответственно:
20
10
32
10
0
22
Теперь позвольте сказать, что я хочу объединить вторую и третью функции вместе, поэтому мне нужно просто вызвать одну функцию вместо двух. Функция будет в этом случае:
def combinedFunction(d,e,f,h,x,y,z):
if h == 1:
print d
print e
print f
if h == 2:
print x
print y
print z
и будет вызываться: combinedFunction(d,e,f,h,x,y,z)
. Как вы можете себе представить, это может стать чрезвычайно раздражающим для гораздо более сложных функций. Также я передаю много разных аргументов, которые не будут использоваться вообще, и каждый из них должен быть сначала объявлен. Например, в примере, если h = 1
, x
, y
и z
еще должны быть переданы в функцию, и, возможно, значение одного из них еще не определено (в этом простом случае это). Я не могу использовать 'combinationFunction (* args)', потому что не каждый аргумент определяется глобально.
TL;DR:
В основном я хочу следующее:
def someFunction(accepts any number of arguments **and** in any order):
# does some stuff using those arguments it received at the time it was called
# it can accept many more parameters if needed
# it won't need to do stuff to a variable that hasn't been passed through
и эта функция вызывается:
someFunction(sends any number of arguments **and** in any order)
# can call the function again using different arguments and a
# different number of arguments if needed
Можно ли это легко достичь?
Использование глобальных переменных внутри функции обычно является плохим подходом. Вместо этого вы можете использовать **kwargs
следующим образом:
def firstFunction(**kwargs):
d = kwargs.get('a') * 2
secondFunction(d=d, **kwargs)
thirdFunction(e=1, **kwargs)
def secondFunction(d, **kwargs):
print d
print kwargs.get('a')
def thirdFunction(**kwargs):
print kwargs.get('e')
firstFunction(a=1, b=3, q=42) # q will not be used
Вы можете использовать dict для передачи данных в функции, но это делает его менее интуитивным при программировании. Каждая функция может преобразовывать аргументы dict, как вам угодно.
def func_a(input_dict):
a = input_dict["a"]
b = input_dict["b"]
print(a+b)
def func_b(input_dict):
c = input_dict["c"]
d = input_dict["d"]
print(c+d)
def combined_func(input_dict):
func_a(input_dict)
func_b(input_dict)
Это очень похоже на kwargs, так что это может быть не то, что вы ищете.
Если я правильно понял, что вы ищете:
def something(*args):
for i in args:
print(i)
some_args = range(10)
something(*some_args)
print('-----------')
something(*some_args[::-1]) # reverse order
Выход:
0
1
2
3
4
5
6
7
8
9
-----------
9
8
7
6
5
4
3
2
1
0
kwargs.get()
. Это все еще немного грязно, но оно делает то, что я хотел.kwargs
- это обычный dict, поэтому вы можете использоватьkwargs.get('a')
,kwargs['a']
и все другие операции dict.