Функциите и техните приятели

„ Програмиране с Python“, ФМИ

Стефан Кънев & Николай Бачийски

12.03.2008г.

Функции

Функции (2)

Ако искате една функция да взема повече от един аргумент, просто ги разделяте със запетаи:

def orderPizza(type, ketchup, mayo):
    order = "I want a " + type + " pizza."
    if ketchup: order += " Please add ketchup."
    if mayo: order += " And please add mayo."

    reply = callAndTell("555-PIZZA", order)
    return reply

>>> orderPizza("Margaritta", False, True)

Аргументи по подразбиране

Може да слагате стойности по подразбиране на аргументите:

def orderPizza(type, ketchup = True, mayo = True):
    order = "I want a " + type + " pizza."
    if ketchup: order += " Please add ketchup."
    if mayo: order += " And please add mayo."

    reply = callAndTell("555-PIZZA", order)
    return reply

>>> orderPizza("Margaritta")

Аргументи по подразбиране (2)

Имайте предвид, че стойностите по подразбиране се инициализират само веднъж

def addBeer(beers = []):
    beers.append("Beer")
    print beers

>>> addBeer()
['Beer']

>>> addBeer()
['Beer', 'Beer']

В този случай е по-добре да сложите beers със стойност по подразбиране None и създавате нов списък в тялото на функцията, ако потребителя не подаде нещо друго.

Извикване с наименовани параметри

При извикване можете да подавате параметрите с имената им. По този начин може да ги дадете в различен ред или да използвате само някои, които имат стойност по подразбиране.

def orderPizza(type, ketchup = True, mayo = True):
    order = "I want a " + type + " pizza."
    if ketchup: order += " Please add ketchup."
    if mayo: order += " And please add mayo."

    reply = callAndTell("555-PIZZA", order)
    return reply

>>> orderPizza(ketchup = False, mayo = False, type = "Margaritta")
>>> orderPizza(type = "Margaritta", ketchup = False)
>>> orderPizza("Margaritta", ketchup = False)

Имена на функции

Python не прави разлика между имена на функции и обекти. Може да ги третирате по еднакъв начин

def scare(): print "Ni!"

>>> sayIt = scare
>>> sayIt()
Ni!
>>> scare()
Ni!
>>> del scare
>>> sayIt()
Ni!
>>> scare()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'scare' is not defined

Имена на функции (2)

Съответно може да предавате функции като аргументи...

def calculate(operation, n1, n2): return operation(n1, n2)
def addition(n1, n2): return n1 + n2
def multiplication(n1, n2): return n1 * n2

>>> calculate(addition, 6, 7)
13
>>> calculate(multiplication, 6, 7)
42
...или като връщани стойности:
def makeStamp(owner):
    def stamp(something):
        return something + " is owned by " + owner
    return stamp

>>> stamper = makeStamp("The Goverment")
>>> print stamper("This thing there")
'This thing there is owned by The Goverment'

Имена на функции (3)

def твърденията се пресмятат по време на изпълнение


def operation(name, n1, n2):
    if name == "addition":
        def oper(x, y):
	    return x + y
    else:
        def oper(x, y):
	    return x * y
    return oper(n1, n2)

>>> operation('addition', 6, 7)
13
>>> operation('multiplication', 6, 7)
42

Динамични аргументи

Като поставите * прeд списък...


>>> preference = ('Margaritta', True, True)
>>> orderPizza(*preference)

...или ** пред речник:


>>> preference = {'type': 'Margaritta', 'mayo': True}
>>> orderPizza(**preference)

Функции с променлив брой аргументи

def sum(prefix, *things):
    result = 0
    for n in things:
        result += n
    print prefix + str(result)

>>> sum("The answer:", 1, 2, 3, 5, 7, 11, 13)
The answer: 42

Функции с променлив брой аргументи (2)

def studentInfo(name, **things):
    print "Hello, my name is " + name
    print "I come from " + things['country']
    print "I like " + things['cheese']

>>> studentInfo('The Black Knight', 
          country = 'Assyria', cheese = 'Limburger')
Hello, my name is The Black Knight
I come from Assyria
I like Limburger

Функции с променлив брой аргументи (3)

Област на видимост

В Python има четири области на видимост

Локален

x = 11

def stuff():
    x = 14
    print x

stuff()
print x

Резултат:

14
11

Глобален

x = 11

def stuff():
    global x
    x = 14
    print x

stuff()
print x

Резултат:

14
14

Глобалните променливи са ЗЛО! Не искайте да ги ползвате.

Обграждаща функция


def f1():
    x = 88
    def f2():
        print x
    return f2

action = f1()
action()	# Отпечатва 88

Анонимни функции


>>> operation = lambda x, y: x * y
>>> print operation(6, 7)
42

Функции от по-висок ред — map


>>> map(lambda x: x ** 2, range(1, 10))
[1, 4, 9, 16, 25, 36, 49, 64, 81]

Функции от по-висок ред — filter


>>> filter(lambda x: x % 2, range(1, 10))
[1, 3, 5, 7, 9]

Функции от по-висок ред — reduce


>>> reduce(lambda x, y: x + y, [3, 5, 7, 11, 13])
39
>>> reduce(lambda x, y: x + y, [3, 5, 7, 11, 13], 3)
42

List comprehension


>>> [x * x for x in range(0, 10)]
[1, 4, 9, 16, 25, 36, 49, 64, 81]

List comprehension (2)


>>> [x * x for x in range(0, 10) if x % 2]
[1, 9, 25, 49, 81]

List comprehension (3)

Може да вложите list comprehension в друг такъв:


>>> nums = range(0, 10)
>>> [(x, y) for x in nums for y in nums if x+y == 13]
[(4, 9), (5, 8), (6, 7), (7, 6), (8, 5), (9, 4)]