1. 程式人生 > 其它 >Python 面試題:函數語言程式設計

Python 面試題:函數語言程式設計

交換變數值

作用域

Python 的作用域可以分為四種:

  • L(Local) 區域性作用域
  • E(Enclosing) 閉包函式外的函式中
  • G(Global) 全域性作用域
  • B(Built-in) 內建作用域

變數/函式 的查詢順序:

  • L –> E –> G –>B

如何查詢模組中的全域性變數和區域性變數

  • globals() :以 dict 的方式儲存所有全域性變數
  • locals():以 dict 的方式儲存所有區域性變數
def foo():
    print("I am a func")

def bar():
    foo="I am a string"
    foo_dup = globals().get("foo")
    foo_dup()

bar()
# 輸出
# I am a func

other = "test"

def foobar():
    name = "MING"
    gender = "male"
    for key,value in locals().items():
        print(key, "=", value)

foobar()

偏函式

  • 如果需要減少某個函式的引數個數,你可以使用 functools.partial() 。 partial() 函式允許你給一個或多個引數設定固定的值,減少接下來被呼叫時的引數個數。
    from functools import partial
    s1 = partial(spam, 1) # a = 1
    s1(2, 3, 4)
    ----
    1 2 3 4

什麼是閉包?

  • 在一個外函式中定義了一個內函式,內函式裡運用了外函式的臨時變數,並且外函式的返回值是內函式的引用。這樣就構成了一個閉包。其實裝飾函式,很多都是閉包。
  • 巢狀函式如果沒有訪問閉包作用域的本地變數,那就不能稱為閉包。
  • 物件是帶有方法的資料,閉包是帶有資料的函式。閉包是一個持久的區域性變數作用域。
  • 閉包是一種特殊情況,如果外函式在結束的時候發現有自己的臨時變數將來會在內部函式中用到,就把這個臨時變數繫結給了內部函式,然後自己再結束。

如何訪問閉包中定義的變數?

  • 通常來講,閉包的內部變數對於外界來講是完全隱藏的。 但是,你可以通過編寫訪問函式並將其作為函式屬性繫結到閉包上來實現這個目的
def sample():
    n = 0
    # Closure function
    def func():
        print('n=', n)

    # Accessor methods for n
    def get_n():
        return n

    def set_n(value):
        nonlocal n
        n = value

    # Attach as function attributes
    func.get_n = get_n
    func.set_n = set_n
    return func

什麼是裝飾器

  • 裝飾器是一種函式,它能在不修改程式碼的情況下擴充套件其他函式的功能。裝飾器的作用為已經存在的物件新增額外功能,能讓之前的程式碼可以複用。
  • 一種 python 的語法糖,與裝飾器模式無關(面向物件的程式設計方法)。

裝飾器的應用場景

  • 異常捕捉:會給自己封裝的每個方法加上這個異常捕捉裝飾器,如果呼叫的封裝方法報錯了,就會進入這個裝飾器,捕捉到指定異常後,我會重新整理頁面,再次執行剛剛報錯的封裝方法,然後會記錄一次失敗日誌

  • 日誌:一般自己封裝的方法都希望有日誌,那如果每個封裝的方法裡單獨呼叫日誌類就會顯得很臃腫重複,所以可以用一個日誌裝飾器代替

  • 前置操作:比如多個方法執行前都需要呼叫同一個方法,那可以將依賴方法寫在裝飾器中

  • 後置操作:比如每次執行方法後都需要還原資料集,可以將清理操作寫在裝飾器中

  • 許可權校驗:執行方法前先進行許可權校驗,校驗通過才會允許執行方法

  • 效能測試

單例模式如何編寫


def singleton(cls):
    _instance = {}

    def inner():
        if cls not in _instance:
            _instance[cls] = cls()
        return _instance[cls]
    return inner

@singleton
class Cls(object):
    def __init__(self):
        pass

cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2))

---

class Singleton(object):
    def __init__(self, cls):
        self._cls = cls
        self._instance = {}
    def __call__(self):
        if self._cls not in self._instance:
            self._instance[self._cls] = self._cls()
        return self._instance[self._cls]

@Singleton
class Cls2(object):
    def __init__(self):
        pass

cls1 = Cls2()
cls2 = Cls2()
print(id(cls1) == id(cls2))

如何實現鏈式函式呼叫