1. 程式人生 > 其它 >記錄學習《流暢的python》的一些知識-----一等函式(1)

記錄學習《流暢的python》的一些知識-----一等函式(1)

技術標籤:pythonlambda函數語言程式設計

記錄我學習《流暢的python》的過程

2021.1.20

1.把函式視作物件
建立並測試一個函式,讀取它的__doc__屬性,再檢查它的型別。

def factorial(n):
    """return n!"""
    return 1 if n < 2 else n *factorial(n-1)

print(factorial(42))

print(factorial.__doc__)

print(type(factorial)
)

在這裡插入圖片描述
通過別的名稱使用函式,再把函式作為引數傳遞。

def factorial(n):
    """return n!"""
    return 1 if n < 2 else n *factorial(n-1)

print(factorial(42))

print(factorial.__doc__)

print(type(factorial))

fact = factorial
print(fact)
print(fact(5))
print(map(factorial, range(11)))
print(list
(map(fact, range(11))))

在這裡插入圖片描述
2.高階函式
接受函式為引數,或者把函式作為結果返回的函式是高階函式。
排序單詞,根據長度:

fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
print(sorted(fruits, key=len))

def reverse(word):
    return word[::-1]

print(reverse('testing'))
print(sorted(fruits, key=reverse))

在這裡插入圖片描述
在函式程式設計正規化中,最為熟知的高階函式有map,filter,reduce。

他們的替代品:

def factorial(n):
    """return n!"""
    return 1 if n < 2 else n *factorial(n-1)
fact = factorial
print(list(map(fact, range(6))))

print([fact(n) for n in range(6)])

"""使用map和filter計算直到5!的奇數階乘列表"""
print(list(map(factorial, filter(lambda n: n % 2, range(6)))))

print([factorial(n) for n in range(6) if n % 2])

在這裡插入圖片描述
在python2中,reduce是內建函式,但是在python3中放在了functools模組中。

from functools import reduce
from operator import add
print(reduce(add, range(100)))

print(sum(range(100)))

在這裡插入圖片描述
all(iterable):每個元素真值則返真,any(iterable):任一真值,返真。

3.匿名函式
lambda關鍵字在python表示式內建立匿名函式。

fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
print(sorted(fruits, key=lambda word: word[::-1]))

在這裡插入圖片描述
4.可呼叫物件
7種可呼叫物件

  • 使用者定義的函式:使用def語句或lambda表示式建立
  • 內建函式:使用C語言實現的函式,len或time.strftime
  • 內建方法:使用C語言實現的方法。dict.get
  • 方法:在類的定義體中定義的函式
  • 類:呼叫時先執行類的__new__方法建立一個例項,然後執行__init__方法,初始化例項,最後把例項返回給呼叫方。
  • 類的例項:類定義了__call__方法,那麼它的例項可以作為函式呼叫。
  • 生成器函式:使用yield關鍵字的函式或方法。

5.使用者定義的可呼叫型別

import random
class BingoCage:
    def __init__(self,items):
        self._items = list(items)
        random.shuffle(self._items) # 隨機排序

    def pick(self):
        try:
            return self._items.pop()
        except IndexError:
            raise LookupError('pick from empty BingoCage')

    def __call__(self):
        return self.pick()

bingo = BingoCage(range(300))
print(bingo.pick())
print(bingo())

在這裡插入圖片描述
callable()函式判斷物件能否呼叫。

6.函式內省
factorial具有的屬性:

def factorial(n):
    """return n!"""
    return 1 if n < 2 else n *factorial(n-1)

a = []
for value in dir(factorial):
    a.append(value)

print(a[0:10])
print(a[10:20])
print(a[20:30])
print(a[30:40])

在這裡插入圖片描述
常規物件沒有而函式有的屬性:

class C: pass # 建立一個空的使用者定義的類
obj = C() # 建立一個例項
def func(): pass # 建立一個空函式
print(sorted(set(dir(func)) - set(dir(obj)))) # 求兩者的差集

在這裡插入圖片描述
7.從定位引數到僅限關鍵字引數
呼叫函式時使用(*)和 **展開可迭代物件,對映到單個引數。

def tag(name, *content, cls=None, **attrs):
    """生成一個或多個HTML標籤"""
    if cls is not None:
        attrs['class'] = cls
    if attrs:
        attr_str = ''.join(' %s="%s"' % (attr, value)
                           for attr, value
                           in sorted(attrs.items()))

    else:
        attr_str = ''
    if content:
        return  '\n'.join('<%s%s>%s</%s>' %
                          (name, attr_str, c, name) for c in content)
    else:
        return '<%s%s />' % (name, attr_str)

print(tag('br'))
print(tag('p', 'hello'))
print(tag('p', 'hello', 'world'))
print(tag('p', 'hello', id=33))
print(tag('p', 'hello', 'world', cls='sidebar'))
print(tag(content="testing", name="img"))
my_tag = {'name': 'img', 'title': 'Sunset Boulevard',
          'src': 'sunset.jpg', 'cls': 'framed'}
print(tag(**my_tag))

在這裡插入圖片描述