ホームページ >バックエンド開発 >Python チュートリアル >Python におけるクロージャの基本的な用途は何ですか?

Python におけるクロージャの基本的な用途は何ですか?

WBOY
WBOY転載
2023-04-24 16:49:111759ブラウズ

    クロージャとは

    クロージャは、別の関数内で定義される関数であり、関数にスコープ内の関数変数がある場合でも、その関数にアクセスできます。処刑を完了し、破壊されました。言い換えれば、クロージャは関数とその環境の組み合わせです。

    簡単に言えば、クロージャは関数の外部から関数内の変数にアクセスできる特別な形式の関数ですが、これらの変数は関数の実行後に破棄されません。 Python でクロージャを使用すると、モジュール式の再利用可能なコードを作成できます。

    Python のクロージャ

    Python の関数はファーストクラスのオブジェクトです。つまり、他のオブジェクトと同様に、渡したり、参照したり、返したり、割り当てたりすることができます。 Python では、関数のネストを通じてクロージャを実装できます。

    これは、クロージャの作成方法を示す簡単な例です:

    def outer_function(x): 
        def inner_function(y): 
            return x + y 
        return inner_function 
        
    closure = outer_function(10)
    print(closure(5))

    この例では、outer_function は 1 つのパラメータを受け入れる関数ですx 、関数 inner_function を返します。 inner_function は、パラメータ y を受け取り、xy の合計を返す関数でもあります。

    コードの最後の行では、クロージャ closure を作成し、戻り値 outer_function(10) (つまり、inner_function##) を渡します。 #)それに値を割り当てます。次に、closure 関数を呼び出し、パラメータ 5 を渡し、戻り値 15 を出力します。この例では、outer_function に渡したパラメータが 10 であるため、#xx の値は 10 です。 クロージャの実装方法

    Python でクロージャを実装するには、関数のネストとデコレータという 2 つの方法があります。

    関数のネスト

    Python では、関数を定義し、この関数内に別の関数を定義して、この内部関数を返すことができます。この内部関数は、クロージャである外部関数の変数にアクセスできます。

    ネスト方法は上記の簡単な例に示したとおりであり、ここでは詳しく説明しません。

    Decorator

    Decorator は、Python でクロージャを実装する別の方法です。デコレータは、関数を引数として受け取り、新しい関数を返す関数です。新しい関数は、元の関数のコードを変更することなく、元の関数に基づいていくつかの新しい関数を追加できます。

    以下は、デコレータを使用してクロージャを実装する方法を示す簡単な例です:

    def my_decorator(func):
        def wrapper():
            print("Before the function is called.") 
            func() 
            print("After the function is called.") 
        return wrapper 
        
    @my_decorator 
    def say_hello():
        print("Hello!")
        say_hello()

    この例では、デコレータ関数

    my_decorator

    を定義し、それを に適用します。関数 say_hello。デコレータ関数は関数をパラメータとして受け取り、新しい関数 wrapper を返します。 wrapper 関数は、元の関数 say_hello に基づいていくつかの新しい関数を追加します。 コードの最後の行では、

    say_hello

    関数を呼び出し、次の内容を出力します:

    関数が呼び出される前に。
    関数が呼び出された後。



    デコレータを通じて、クロージャを正常に実装しました。

    クロージャのアプリケーション

    クロージャには Python での多くのアプリケーション シナリオがあります。一般的なシナリオをいくつか示します:

    1. 遅延実行

    クロージャは使用できます。遅延実行を実装します。つまり、関数が呼び出されたときにのみ計算が実行されます。これにより、特に複雑な式を評価する場合に、プログラムのパフォーマンスが向上します。

    次の例は、クロージャを使用して遅延実行を実装する方法を示しています:

    def delayed_sum(a, b):
        def sum(): 
            return a + b 
        return sum 
        
    result = delayed_sum(1, 2) 
    print(result()) # 3

    この例では、2 つのパラメータを受け入れる

    layed_sum

    関数を定義します

    ab を返し、関数 sum を返します。 layed_sum 関数を呼び出すと、ab の合計は計算されませんが、sum 関数が返されます。 sum 関数を呼び出すと、ab の合計が計算され、結果が返されます。 2. 結果のキャッシュ

    クロージャは、特に複雑な関数を計算する場合に関数の結果をキャッシュするために使用でき、これによりプログラムのパフォーマンスが大幅に向上します。

    次の例は、クロージャを使用してキャッシュされた結果を実装する方法を示しています:

    def memoize(func):
        cache = {} 
        
        def wrapper(*args):
            if args in cache: 
                return cache[args] 
            result = func(*args) 
            cache[args] = result 
            return result 
        return wrapper 
                                            
    @memoize 
    def fibonacci(n): 
        if n in (0, 1):
            return n 
        return fibonacci(n - 1) + fibonacci(n - 2) 
        
    print(fibonacci(10)) # 55

    この例では、結果をキャッシュできる

    memoize

    デコレータ関数を定義します。装飾された関数の。

    fibonacci 関数では、memoize デコレータを使用して、フィボナッチ数列の値の繰り返し計算を回避します。最初に fibonacci 関数を呼び出すと、fibonacci(0)fibonacci(1) の値が計算され、それらがキャッシュに保存されます。次回 fibonacci 関数を呼び出すと、まず必要な値がキャッシュ内で計算されているかどうかがチェックされ、計算されている場合はキャッシュ内の結果が直接返され、そうでない場合は再度計算されます。 3. プライベート変数と同様の関数を実装する

    Python では、Java や C のようなプライベート変数を直接定義できません。ただし、クロージャを使用してプライベート変数と同様の機能を実現できます。

    下面是一个例子,演示了如何使用闭包实现私有变量:

    def counter():
        count = 0 
        def inner():
            nonlocal count 
            count += 1 
            return count 
        return inner 
       
    c1 = counter() 
    c2 = counter() 
    print(c1()) # 1 
    print(c1()) # 2 
    print(c2()) # 1 
    print(c2()) # 2

    在这个例子中,我们定义了一个counter函数,它返回一个inner函数。inner函数可以访问count变量,而count变量是在counter函数中定义的。由于 Python 中没有直接定义私有变量的语法,我们使用了一个内部函数来访问外部函数中的变量。这样,我们就可以实现类似于私有变量的功能。

    在调用c1c2时,它们返回的inner函数中的count变量是不同的。这是因为每次调用counter函数时,它都会返回一个新的inner函数,每个inner函数都有自己的count变量。

    闭包的优缺点

    闭包有很多优点,例如:

    • 可以避免使用全局变量,提高程序的可维护性;

    • 可以实现类似于私有变量的功能,提高程序的安全性;

    • 可以实现延迟执行和缓存结果,提高程序的性能。

    但是,闭包也有一些缺点,例如:

    • 可能会占用较多的内存空间,因为闭包会保留外部函数的状态;

    • 可能会导致循环引用的问题,如果闭包中引用了外部函数的变量,而这些变量又引用了闭包中的变量,就会出现循环引用的问题。

    小结

    Python中的闭包是一种非常强大的编程技术,它可以帮助我们提高程序的可维护性、安全性和性能。通过闭包,我们可以避免使用全局变量、实现类似于私有变量的功能、实现延迟执行和缓存结果等。

    要使用闭包,我们需要了解闭包的原理和使用方法。在Python中,可以使用嵌

    套函数来实现闭包。在定义闭包时,需要注意外部函数和内部函数的作用域、变量的生命周期等问题,以避免出现意外的错误。

    在实际编程中,可以使用闭包来实现许多有用的功能,例如缓存结果、实现状态机、实现装饰器等。对于有经验的Python程序员来说,闭包已经成为不可或缺的一部分。

    在使用闭包时,需要注意以下几点:

    • 尽量避免在闭包中修改外部函数的变量。如果需要修改变量,应该使用nonlocal关键字。

    • 闭包中的变量是在函数定义时绑定的,而不是在函数调用时绑定的。因此,如果在闭包中引用了外部函数的变量,应该确保这些变量在闭包定义时是可用的。

    • 闭包中引用的外部函数的变量会一直存在,直到闭包被销毁。因此,如果闭包中引用了外部函数的大量变量,可能会占用大量的内存空间。

    以上がPython におけるクロージャの基本的な用途は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。