Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

python: возращаемое значение def

29K
30 сентября 2009 года
Ander Skirnir
109 / / 08.06.2009
Долго искал, но не нашел даже на оффе, имеет ли def возвращаемое значение. Тем не менее, много где пишут, что любая функция в питоне имеет. Интересно, является ли def функцией, или это некая специальная форма?

Мне это надо, чтобы в некоторых ситуациях использовать возращаемое def'ом значение сразу же (в качестве функции, или её вызова или еще чего). Кроме того, интересно, насколько аппликативен питон. Конечно, можно использовать лямбду (её возвращаемое значение - сама ф-ция) и присваивать её переменной, но хотелось бы честное поименование функции.
6
30 сентября 2009 года
George
4.1K / / 05.01.2007
Найдено в книге Лутца:
 
Код:
def adder(a, b=1, *c):
    return a + b + c[0]


upd.
Подсветка питоновского кода не понравилась. ГЛючная и страшненькая =)
87
01 октября 2009 года
Kogrom
2.7K / / 02.02.2008
Добавлю:
Код:
def FuncRet():
    return 1

def FuncNoRet():
    pass

a = FuncRet
print a()
print a

a = FuncNoRet
print a()
print a


Первое: переменной a я присвоил функцию. Всё работает. Это заложено в языке. То же самое можно сделать и с лямбдой.

Второе: даже если я не указал, что функция что-то возвращает, то она все равно возвращает None. Это бывает удобно при работе с контейнером функций (например, так я использовал словарь с функциями в своей Адресной Книге).
5
01 октября 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Ander Skirnir
Долго искал, но не нашел даже на оффе, имеет ли def возвращаемое значение.

Конструкция def является предложением, а не выражением и потому не возвращает результат.
Семантика def в некотором смысле эквивалентна семантике let из ML-семейства, она подразумевает связывание с именем (в текущем контексте), следующим за ним, некоей функции.

14
01 октября 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: Washington

Подсветка питоновского кода не понравилась. ГЛючная и страшненькая =)


Это в чем? В книге? :)

Цитата:
связывание с именем (в текущем контексте), следующим за ним, некоей функции


..а функция без имени - лябда. Насколько я понимаю.

87
01 октября 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Phodopus
..а функция без имени - лябда. Насколько я понимаю.



Не совсем, насколько я понимаю. Лямбда - это функция, содержащая одно выражение (expression). Тут нельзя использовать блоки кода, созданные с помощью if, while и т.п. То есть лямбда не является полноценной функцией.

Можно и у простой функции имя удалить, но от этого она лямбдой не станет:

Код:
def FuncRet():
    return 1

a = FuncRet
print a()

del FuncRet

lm = lambda: 2 + 3

print lm # <function <lambda> at 0x...>
print a # <function FuncRet at 0x...>

print FuncRet() # oops


Хотя, возможно, в этом случае я вру с терминологией :)
6
01 октября 2009 года
George
4.1K / / 05.01.2007
Цитата: Phodopus
Это в чем? В книге? :)


та не. это я про [ highlight = python ] [ /highlight ]

29K
01 октября 2009 года
Ander Skirnir
109 / / 08.06.2009
hardcase правильно понял, о чём я спрашивал. Именно о возможности использовать возвращаемое обьявителем функции def значение тут же.

На питоно-псевдо-коде что-то типа такого (вызов g):
 
Код:
def g (f) :
     ...

def f (fl) :
     return [for i in fl :
                    g(def i
                            ...)]


Конечно, удобнее, когда обьявители функций всё-же являются функциями и возвращает значение, но в данном случае не критично - то, что требуется можно через присвоенные переменным лямбды сделать.

Цитата:
Лямбда - это функция, содержащая одно выражение (expression).


Ну в общем случае это просто безымянная функция. В питоне их решили ограничить одним выражением.

6
01 октября 2009 года
George
4.1K / / 05.01.2007
приведу ка я выдержку из книги:
[quote=Лутц]
def creates an object and assigns it to a name. When Python reaches and runs
a def statement, it generates a new function object and assigns it to the function’s
name. As with all assignments, the function name becomes a reference to the func-
tion object. There’s nothing magic about the name of a function—as you’ll see,
the function object can be assigned to other names, stored in a list, and so on.
Function objects may also have arbitrary user-defined attributes attached to them
to record data.
lambda creates an object but returns it as a result. Functions may also be created
with the lambda expression, a feature that allows us to in-line function definitions
in places where a def statement won’t work syntactically
[/quote]
еще чуток про лямбду:
[quote=Лутц]
Besides the def statement, Python also provides an expression form that generates
function objects. Because of its similarity to a tool in the Lisp language, it’s called
lambda.* Like def, this expression creates a function to be called later, but it returns the
function instead of assigning it to a name. This is why lambdas are sometimes known
as anonymous (i.e., unnamed) functions. In practice, they are often used as a way to
inline a function definition, or to defer execution of a piece of code.
[/quote]
29K
01 октября 2009 года
Ander Skirnir
109 / / 08.06.2009
Всем спасибо за инфу.

Цитата:
Because of its similarity to a tool in the Lisp language, it’s called
lambda.



Ну, не совсем. В Лиспе лямбды не ограничены одним выражением. Ну и в питоне это ограничение по-идее не так страшно: можно заменить все кодоблоки на аналогичные функции: типа func-for(init-expr, continuation-pred, some-lambda) и преобразовать любой код, состоящий из блоков и тп в одно выражение.

87
01 октября 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Ander Skirnir

На питоно-псевдо-коде что-то типа такого (вызов g):
 
Код:
def g (f) :
     ...

def f (fl) :
     return [for i in fl :
                    g(def i
                            ...)]


Если я правильно понимаю что требуется, то так надо:

 
Код:
def g (f) :
     ...

def f (fl) :
     return [for i in fl : g(i)]

и будет новый список вместо fl.
29K
01 октября 2009 года
Ander Skirnir
109 / / 08.06.2009
Не, надо чтоб обьявлялась функция с именем i и результат обьявления (функциональный обьект, например) передавался аргументом функции g.
87
01 октября 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Ander Skirnir
Не, надо чтоб обьявлялась функция с именем i и результат обьявления (функциональный обьект, например) передавался аргументом функции g.


Опять я ничего не понял. Мне бы на рабоче-крестьянском, а не на аспирантском :)

А что в fl содержится? Почему туда не засунуть функции? Вот и будут они передаваться в g.

В Питоне все переменные вроде как указатели без типа, указывают на объекты в памяти. Объектом может быть и функция. Одна и та же переменная вначале может указывать на число, потом на список, потом на функцию. Привязывай к чему хочешь, когда хочешь.

В g имя уже не дойдет - только объект, который будет привязан к локальной переменной в g.

29K
01 октября 2009 года
Ander Skirnir
109 / / 08.06.2009
Вообщем, можно убрать вообще весь код кроме g(def i ...)
Надобно одновременно определять функцию с именем, заданным переменной i и потом эту же функцию передавать параметром функции g, подобно тому, как если бы она была лямбдой g(lambda ...).
5
01 октября 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Ander Skirnir
Надобно одновременно определять функцию с именем, заданным переменной i ...

Попахивает черной магией ::)
Имхо на лету (в рантайме) создавать именованную функцию.... как-то, э-э-э, странно, я бы сказал.

Но все-таки нет ничего невозможного: http://snipplr.com/view/17819/python--create-a-function-in-runtime/

29K
02 октября 2009 года
Ander Skirnir
109 / / 08.06.2009
Цитата:
Попахивает черной магией


Ну если-бы это делалось на си, си++ и тп - тогда действительно было ею, но для динамических языков - это не просто нормально, но даже подход.

Цитата:
Но все-таки нет ничего невозможного: http://snipplr.com/view/17819/python...on-in-runtime/


Спасибо, это интересно. Но жутко напряжно и как-то некрасиво. Возможно, есть вариант сделать лучше через eval.

На Лиспе, например, я бы так делал:

Функция обьявляющая функцию:

 
Код:
(defun define-function (name args code)
  (eval `(defun ,name ,args ,code)))


Функционал, обьявляющий функции, описанные в списке definitions-list и применяющий функцию func-to-apply к результату каждого обьявления:
 
Код:
(defun define-funcs-and-apply (definitions-list func-to-apply)
  (loop for f in definitions-list
          do (funcall func-to-apply (apply 'define-function f))))


Пример использования для одновременного обьявления и инстанцирования continuation-генератора последовательных натуральных чисел начиная с заданного:
 
Код:
(let ((generator-registry '()))
  (define-funcs-and-apply '((gen-1 (x) (lambda nil (setq x (+ x 1))))
                                       (gen-2 (x) (lambda nil (setq x (+ x 2)))))
                                     (lambda (f) (push (funcall f 0) generator-registry)))
  (defun call-generator (n) (funcall (nth n generator-registry))))


Вышеприведённый код обьявляет две функции-обьявителя генератора (gen-1 и gen-2), которые возвращают функцию-генератор последовательных (с шагом 1 и 2 соответственно) значений начиная с заданного-при-вызове gen-1 или gen-2 аргумента, и одновременно вызывает эти функции с аргументом 0, инстанцируя два генератора, которые потом можно вызывать обьявляемой в этом же куске кода функцией-аксессором call-generator.

(call-generator 1)
>> 1
(call-generator 2)
>> 2
(call-generator 2)
>> 4
(call-generator 1)
>> 2
(setq new-generator (gen-1 66))
(funcall new-generator)
>> 67

Конечно, не самый практичный пример использования, но наглядный.
87
02 октября 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Ander Skirnir
На Лиспе, например, я бы так делал...



В том и проблема, что лисповские подходы требуется также ив Питоне найти. На деле там аналогичные по смыслу практические задачи могут решаться по другому. Скажем, генератор может задаться совсем просто:

 
Код:
import itertools

a = itertools.count(5)
print a.next(), # 5
print a.next(), # 6
print a.next() # 7


или так:

Код:
def MyGen(first, mult):
    res = first
    while True:
        yield res
        res *= mult

gen1 = MyGen(6, 2)
gen2 = MyGen(8, 3)
print gen1 .next(), # 6
print gen1 .next(), # 12
print gen1 .next() # 24

print gen2.next(), # 8
print gen2.next(), # 24
print gen2.next() # 72


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

Но, чую, что это беседа нескольких глухих :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог