Аргумент при вызове функций по цепочке

User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Аргумент при вызове функций по цепочке

Post by perasperaadastra »

У меня сложилась такая ситуация:
вызывается функция 1, из нее — ф2, а из ф2 - ф3. Ф3 использует аргумент, который определяется в головном коде. Таким образом, переменная передается из головы в ф1, в ф2 и, наконец, ф3, но не используется в ф1 и ф2, кроме как для передачи дальше по цепочке.

Как правильно в таких случаях действовать? Игнорировать? Или объявить переменную глобальной?
User avatar
Relict17
Уже с Приветом
Posts: 573
Joined: 15 Jan 2016 02:50

Re: Аргумент при вызове функций по цепочке

Post by Relict17 »

Уж точно не глобальную переменную! :)

В чем вообще проблема? ну передаете по цепочке и передавайте на здоровье. Все кошерно, локально и тред-сейфово.
Oleg-NY
Уже с Приветом
Posts: 2414
Joined: 16 Jul 2004 00:32
Location: NY, NY

Re: Аргумент при вызове функций по цепочке

Post by Oleg-NY »

Если только это не методы, а иначе, почему и не "глобальную переменную"?
Oleg-NY
Уже с Приветом
Posts: 2414
Joined: 16 Jul 2004 00:32
Location: NY, NY

Re: Аргумент при вызове функций по цепочке

Post by Oleg-NY »

Oleg-NY wrote:Если только это не методы, а иначе, почему и не "глобальную переменную"?
P.S.: И вообще, вдруг это про линух? Тогда про тред-сейфовость можно поговорить отдельно... еще полно любителей форков и глобальных, да еще и статических переменных. И ведь таки ж сэйф! ;)
Last edited by Oleg-NY on 11 Oct 2016 22:10, edited 1 time in total.
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Аргумент при вызове функций по цепочке

Post by perasperaadastra »

Неудобно в том, что куча "ненужных" аргументов, которые иногда забываю написать, а потом чешу репу, пытаясь понять, почему такая-то функция отработала по exception, когда все должно было быть нормально. :)
User avatar
Мальчик-Одуванчик
Уже с Приветом
Posts: 15526
Joined: 27 Sep 2007 22:53

Re: Аргумент при вызове функций по цепочке

Post by Мальчик-Одуванчик »

Обьявите функцию 4 как замыкание в области видимости функции 1
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Аргумент при вызове функций по цепочке

Post by perasperaadastra »

А как это по английски (чтобы погуглить, как это сделать в питоне)?
User avatar
M. Ridcully
Уже с Приветом
Posts: 12017
Joined: 08 Sep 2006 20:07
Location: Силиконка

Re: Аргумент при вызове функций по цепочке

Post by M. Ridcully »

Мальчик-Одуванчик wrote:Обьявите функцию 4 как замыкание в области видимости функции 1
Пришёл и всё опошлил. :D

Кстати, ТС вроде в соседнем топике говорил, что на Питоне пишет, так вот там с замыканиями мудохаться надо, насколько я помню.
Мир Украине. Свободу России.
helg
Уже с Приветом
Posts: 4827
Joined: 15 May 2001 09:01

Re: Аргумент при вызове функций по цепочке

Post by helg »

perasperaadastra wrote:А как это по английски (чтобы погуглить, как это сделать в питоне)?
Это, пардон майн френч, клошар.
Oleg-NY
Уже с Приветом
Posts: 2414
Joined: 16 Jul 2004 00:32
Location: NY, NY

Re: Аргумент при вызове функций по цепочке

Post by Oleg-NY »

perasperaadastra wrote:А как это по английски (чтобы погуглить, как это сделать в питоне)?
Дык вроде Гугл и с русским не плохо дружит. Вот оно, преклонение перед Западом в действии! )))
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Аргумент при вызове функций по цепочке

Post by perasperaadastra »

helg wrote:
perasperaadastra wrote:А как это по английски (чтобы погуглить, как это сделать в питоне)?
Это, пардон майн френч, клошар.
Клозюры. :D Пойду читать про их.
Oleg-NY wrote:
perasperaadastra wrote:А как это по английски (чтобы погуглить, как это сделать в питоне)?
Дык вроде Гугл и с русским не плохо дружит. Вот оно, преклонение перед Западом в действии! )))
:D И правда, можно найти на русском, но терминология тогда становится довольно непонятной, потому что все, что я знаю про питон, учил на английском языке.
Deckel
Ник закрыт за хамство.
Posts: 357
Joined: 16 Feb 2014 18:34

Re: Аргумент при вызове функций по цепочке

Post by Deckel »

Эта тема и мне интересна. Отпишитесь тут, как найдёте для питона?
User avatar
f_evgeny
Уже с Приветом
Posts: 10367
Joined: 12 Apr 2001 09:01
Location: Lithuania/UK

Re: Аргумент при вызове функций по цепочке

Post by f_evgeny »

perasperaadastra wrote:У меня сложилась такая ситуация:
вызывается функция 1, из нее — ф2, а из ф2 - ф3. Ф3 использует аргумент, который определяется в головном коде. Таким образом, переменная передается из головы в ф1, в ф2 и, наконец, ф3, но не используется в ф1 и ф2, кроме как для передачи дальше по цепочке.

Как правильно в таких случаях действовать? Игнорировать? Или объявить переменную глобальной?
Лично я таких ситуаций стараюсь избегать, но если это Питон, можно передавать так:

Code: Select all

def f(**kwargs):
    print "f kwargs =",kwargs   

def f1(**kwargs):
    print "f1 kwargs =", kwargs
    f(**kwargs)

> f1(a=1, b=2)
f1 kwargs = {'a': 1, 'b': 2}
f kwargs = {'a': 1, 'b': 2}
Где запись **kwargs означает примерно следующее: Любое число именованных аргументов.
Вместо kwargs можно использовать другое имя, но это используется традиционно.
Дальше, все будет только хуже. Оптимист.
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Аргумент при вызове функций по цепочке

Post by perasperaadastra »

В f1 вы написали вызов f(**kwargs). А просто f(kwargs) не будет работать? Я думал, что f1 получит параметры и положит их в словарь kwargs, а звездочки нужны только в определении функции... Наверно я что-то не так понял...

Кстати, доступ к переменной a в f будет через kwargs['a'] или функция автоматически распакует словарь и добавит перменную а?
User avatar
f_evgeny
Уже с Приветом
Posts: 10367
Joined: 12 Apr 2001 09:01
Location: Lithuania/UK

Re: Аргумент при вызове функций по цепочке

Post by f_evgeny »

perasperaadastra wrote:В f1 вы написали вызов f(**kwargs). А просто f(kwargs) не будет работать? Я думал, что f1 получит параметры и положит их в словарь kwargs, а звездочки нужны только в определении функции... Наверно я что-то не так понял...

Кстати, доступ к переменной a в f будет через kwargs['a'] или функция автоматически распакует словарь и добавит перменную а?

Code: Select all

def f1(**kwargs):
      2     print "f1 kwargs =", kwargs
----> 3     f(kwargs)
      4 

TypeError: f() takes exactly 0 arguments (1 given)
Если Вы передаете просто kwargs, это значит Вы передаете один позиционный аргумент типа словарь. А функция f(**kwargs) вообще не имеет таких параметров. А звездочки распаковывают словарь в список именованных аргументов произвольной длины.
доступ к этим аргументам как к словарю.
Кстати, большую часть ответов можно было получить посмотрев на приведенные примеры. Это я не из головы написал, это вывод интерактивного режима питона. Этим нужно научиться польоваться обязательно. В него переходят так: запускают консоль и запускают команду питон без параметров. Консолью питона можно пользоваться как:
- Калькулятором
- Для проверки особенностей работы Питона
- Для чтения хелпа по Питону
Дальше, все будет только хуже. Оптимист.
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Аргумент при вызове функций по цепочке

Post by perasperaadastra »

Извините, ночью уже не хватило сил ставить эксперимент в консоли :)

Я никак не могу взять в толк, чем это принципиально отличается от

Code: Select all

def f2(kwargs):
    print "f2 kwargs =",kwargs
def f1(kwargs):
    print "f1 kwargs =", kwargs
    f2(kwargs)

a = 1
b = 2
f1({'a':a, 'b':b})
Тот же словарь, те же возможности? Или в вызове f1(a=1,b=2) есть что-то более кошерное?
User avatar
f_evgeny
Уже с Приветом
Posts: 10367
Joined: 12 Apr 2001 09:01
Location: Lithuania/UK

Re: Аргумент при вызове функций по цепочке

Post by f_evgeny »

perasperaadastra wrote:Извините, ночью уже не хватило сил ставить эксперимент в консоли :)

Я никак не могу взять в толк, чем это принципиально отличается от

Code: Select all

def f2(kwargs):
    print "f2 kwargs =",kwargs
def f1(kwargs):
    print "f1 kwargs =", kwargs
    f2(kwargs)

a = 1
b = 2
f1({'a':a, 'b':b})
Тот же словарь, те же возможности? Или в вызове f1(a=1,b=2) есть что-то более кошерное?
Ну, навскидку тем:
- вообще можно ничего не передавать

Code: Select all

 def f1(**kwargs):
   ...:     print "f1 kwargs =", kwargs
   ...:     

In [2]: f1()
f1 kwargs = {}

In [3]: def f2(kwargs):
    print "f2 kwargs =", kwargs
   ...:     

In [4]: f2()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-fdec4c1c071f> in <module>()
----> 1 f2()

TypeError: f2() takes exactly 1 argument (0 given)
- в конце будет функция, которая принимает не словарь, а именованные аргументы

Code: Select all

def f1(a=None, b=None):
    print "f1  a =", a
    print "f1 b =", b


In [11]: kwargs = {'a': 1, 'b': 2}

In [12]: f1(**kwargs)
f1  a = 1
f1 b = 2

In [13]: 
Причем это может быть вообще не Ваша функция в конце и даже Вы можете не знать, какие там параметры.
Дальше, все будет только хуже. Оптимист.
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Аргумент при вызове функций по цепочке

Post by perasperaadastra »

Ааа! Теперь понятно! Большое спасибо за объяснение! :fr:
User avatar
f_evgeny
Уже с Приветом
Posts: 10367
Joined: 12 Apr 2001 09:01
Location: Lithuania/UK

Re: Аргумент при вызове функций по цепочке

Post by f_evgeny »

perasperaadastra wrote:Ааа! Теперь понятно! Большое спасибо за объяснение! :fr:
Any time.
Дальше, все будет только хуже. Оптимист.
User avatar
perasperaadastra
Уже с Приветом
Posts: 20128
Joined: 21 Feb 2009 22:55
Location: Лох Онтарио

Re: Аргумент при вызове функций по цепочке

Post by perasperaadastra »

Жаль, я не знал про именованные аргументы раньше! А то как раз недавно столкнулся с проблемой, когда случайно поменял порядок аргументов при вызове функции, а в определении остался старый порядок. Найти проблему было, конечно, не сложно, но можно было бы ее совсем избежать, если бы использовал именованные аргументы.

Я немножко адаптировал пример под свою ситуацию с "лишними" аргументами:

Code: Select all

def f2(x=0, b=0, **remainder):
    print "f2 formal args:  ", x, ", ", b
    print "f2 arg remainder:", remainder

def f1(d, **remainder):
    print "f1 formal arg:   ", d
    print "f1 arg remainder:", remainder
    x = d*2
    f2(x, **remainder)

f1(9, a=1, b=3, c=7)
Очень удобно!

Но, в принципе, мне было не обязательно передавать "лишние" аргументы из одной функции в другую. Все вложенные функции имеют read-only access к переменным из более внешних. Это, как я понимаю и есть те самые "клошары", о которых шла речь выше.

Return to “Вопросы и новости IT”