Hàm một phần Python là gì?

Mô-đun dành cho các chức năng bậc cao hơn. các chức năng hành động hoặc trả về các chức năng khác. Nói chung, bất kỳ đối tượng có thể gọi nào cũng có thể được coi là một chức năng cho các mục đích của mô-đun này

Mô-đun xác định các chức năng sau

@công cụ chức năng. bộ đệm(user_function)

Bộ đệm chức năng không giới hạn nhẹ đơn giản. Đôi khi được gọi là "ghi nhớ"

Trả về giống như

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)
8, tạo một lớp bao bọc mỏng xung quanh tra cứu từ điển cho các đối số của hàm. Bởi vì nó không bao giờ cần loại bỏ các giá trị cũ, giá trị này nhỏ hơn và nhanh hơn so với giới hạn kích thước

Ví dụ

@cache
def factorial(n):
    return n * factorial(n-1) if n else 1

>>> factorial(10)      # no previously cached result, makes 11 recursive calls
3628800
>>> factorial(5)       # just looks up cached value result
120
>>> factorial(12)      # makes two new recursive calls, the other 10 are cached
479001600

Bộ đệm là luồng an toàn nên chức năng được bao bọc có thể được sử dụng trong nhiều luồng

Mới trong phiên bản 3. 9

@công cụ chức năng. cached_property(chức năng)

Chuyển đổi một phương thức của một lớp thành một thuộc tính có giá trị được tính một lần và sau đó được lưu vào bộ nhớ cache dưới dạng một thuộc tính bình thường cho vòng đời của thể hiện. Tương tự như , với việc bổ sung bộ nhớ đệm. Hữu ích cho các thuộc tính được tính toán đắt tiền của các phiên bản không thể thay đổi một cách hiệu quả

Ví dụ

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)

Cơ chế của hơi khác so với. Một thuộc tính chặn thuộc tính thông thường ghi trừ khi một setter được xác định. Ngược lại, cached_property cho phép ghi

Trình trang trí cached_property chỉ chạy khi tra cứu và chỉ khi một thuộc tính cùng tên không tồn tại. Khi nó chạy, cached_property ghi vào thuộc tính có cùng tên. Thuộc tính tiếp theo đọc và ghi được ưu tiên hơn phương thức cached_property và nó hoạt động như một thuộc tính bình thường

Giá trị được lưu trong bộ nhớ cache có thể bị xóa bằng cách xóa thuộc tính. Điều này cho phép phương thức cached_property chạy lại

Lưu ý, trình trang trí này can thiệp vào hoạt động của từ điển chia sẻ khóa PEP 412. Điều này có nghĩa là từ điển phiên bản có thể chiếm nhiều dung lượng hơn bình thường

Ngoài ra, trình trang trí này yêu cầu thuộc tính

sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order
3 trên mỗi phiên bản là một ánh xạ có thể thay đổi. Điều này có nghĩa là nó sẽ không hoạt động với một số loại, chẳng hạn như siêu lớp (vì thuộc tính
sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order
3 trên các thể hiện loại là proxy chỉ đọc cho không gian tên lớp) và những thuộc tính chỉ định
sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order
5 mà không bao gồm
sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order
3 là một trong các vị trí được xác định (như các lớp đó

Nếu không có ánh xạ có thể thay đổi hoặc nếu muốn chia sẻ khóa tiết kiệm không gian, hiệu ứng tương tự như có thể đạt được bằng cách xếp chồng lên trên

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)

Mới trong phiên bản 3. 8

công cụ chức năng. cmp_to_key(chức năng)

Chuyển đổi một chức năng so sánh kiểu cũ thành một. Được sử dụng với các công cụ chấp nhận các chức năng chính (chẳng hạn như , , , , , ). Hàm này chủ yếu được sử dụng làm công cụ chuyển đổi cho các chương trình được chuyển đổi từ Python 2 hỗ trợ sử dụng các hàm so sánh

Hàm so sánh là bất kỳ hàm có thể gọi nào chấp nhận hai đối số, so sánh chúng và trả về một số âm cho giá trị nhỏ hơn, 0 cho giá trị bằng hoặc số dương cho giá trị lớn hơn. Hàm khóa là một hàm có thể gọi được chấp nhận một đối số và trả về một giá trị khác được sử dụng làm khóa sắp xếp

Ví dụ

sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order

Để biết các ví dụ sắp xếp và hướng dẫn sắp xếp ngắn gọn, hãy xem

Mới trong phiên bản 3. 2

@công cụ chức năng. lru_cache(user_function)@công cụ chức năng. lru_cache(kích thước tối đa=128 , đã nhập=Sai)

Trình trang trí để bọc một chức năng có thể gọi được ghi nhớ giúp tiết kiệm tối đa các cuộc gọi gần đây nhất. Nó có thể tiết kiệm thời gian khi một hàm đắt tiền hoặc hàm liên kết I/O được gọi định kỳ với cùng các đối số

Bộ đệm là luồng an toàn nên chức năng được bao bọc có thể được sử dụng trong nhiều luồng

Vì một từ điển được sử dụng để lưu kết quả vào bộ đệm, nên các đối số vị trí và từ khóa cho hàm phải có thể băm được

Các mẫu đối số riêng biệt có thể được coi là các cuộc gọi riêng biệt với các mục nhập bộ nhớ cache riêng biệt. Ví dụ:

@lru_cache
def count_vowels(sentence):
    return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')
7 và
@lru_cache
def count_vowels(sentence):
    return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')
8 khác nhau về thứ tự đối số từ khóa và có thể có hai mục nhập bộ nhớ cache riêng biệt

Nếu user_function được chỉ định, nó phải là một hàm có thể gọi được. Điều này cho phép trình trang trí lru_cache được áp dụng trực tiếp cho chức năng người dùng, để kích thước tối đa ở giá trị mặc định là 128

@lru_cache
def count_vowels(sentence):
    return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')

Nếu kích thước tối đa được đặt thành

@lru_cache
def count_vowels(sentence):
    return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')
9, tính năng LRU sẽ bị tắt và bộ đệm có thể phát triển không giới hạn

Nếu typed được đặt thành true, các đối số hàm thuộc các loại khác nhau sẽ được lưu vào bộ đệm riêng. Nếu gõ là sai, việc triển khai thường sẽ coi chúng là các cuộc gọi tương đương và chỉ lưu trữ một kết quả duy nhất. (Một số kiểu như str và int có thể được cache riêng ngay cả khi gõ sai. )

Lưu ý, tính đặc hiệu của loại chỉ áp dụng cho các đối số ngay lập tức của hàm chứ không phải nội dung của chúng. Các đối số vô hướng,

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
0 và
@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
1 được coi là các lệnh gọi riêng biệt với các kết quả khác biệt. Ngược lại, các đối số của bộ dữ liệu
@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
2 và
@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
3 được coi là tương đương

Hàm được bao bọc được trang bị bằng hàm

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
4 trả về giá trị mới hiển thị cho kích thước tối đa và đã nhập. Đây là chỉ cho mục đích thông tin. Thay đổi các giá trị không có hiệu lực

Để giúp đo lường hiệu quả của bộ đệm và điều chỉnh tham số kích thước tối đa, hàm bao bọc được trang bị bằng hàm

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
6 trả về hiển thị số lần truy cập, bỏ lỡ, kích thước tối đa và kích thước cuộn

Trình trang trí cũng cung cấp chức năng

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
7 để xóa hoặc vô hiệu hóa bộ đệm

Chức năng cơ bản ban đầu có thể truy cập được thông qua thuộc tính

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
8. Điều này hữu ích cho việc xem xét nội quan, để bỏ qua bộ đệm hoặc để gói lại chức năng bằng một bộ đệm khác

Bộ đệm giữ các tham chiếu đến các đối số và trả về các giá trị cho đến khi chúng hết hạn hoặc cho đến khi bộ đệm bị xóa

Nếu một phương thức được lưu vào bộ đệm, thì đối số đối tượng

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
9 sẽ được đưa vào bộ đệm. Nhìn thấy

An hoạt động tốt nhất khi các cuộc gọi gần đây nhất là yếu tố dự đoán tốt nhất cho các cuộc gọi sắp tới (ví dụ: các bài báo phổ biến nhất trên máy chủ tin tức có xu hướng thay đổi mỗi ngày). Giới hạn kích thước của bộ đệm đảm bảo rằng bộ đệm không phát triển mà không bị ràng buộc đối với các quy trình chạy dài như máy chủ web

Nói chung, chỉ nên sử dụng bộ đệm LRU khi bạn muốn sử dụng lại các giá trị đã tính trước đó. Theo đó, sẽ không hợp lý khi lưu trữ các hàm có tác dụng phụ, các hàm cần tạo các đối tượng có thể thay đổi riêng biệt trên mỗi lệnh gọi hoặc các hàm không thuần túy như time() hoặc random()

Ví dụ về bộ đệm LRU cho nội dung web tĩnh

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

Ví dụ về tính toán hiệu quả các số Fibonacci bằng cách sử dụng bộ đệm để triển khai kỹ thuật lập trình động

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

Mới trong phiên bản 3. 2

Đã thay đổi trong phiên bản 3. 3. Đã thêm tùy chọn đã nhập.

Đã thay đổi trong phiên bản 3. 8. Đã thêm tùy chọn user_function.

Mới trong phiên bản 3. 9. Đã thêm chức năng

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
4

@công cụ chức năng. tổng_đặt hàng

Đưa ra một lớp xác định một hoặc nhiều phương thức sắp xếp so sánh phong phú, trình trang trí lớp này cung cấp phần còn lại. Điều này đơn giản hóa nỗ lực liên quan đến việc chỉ định tất cả các hoạt động so sánh phong phú có thể

Lớp phải xác định một trong số

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
1,
@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
2,
@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
3 hoặc
@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
4. Ngoài ra, lớp nên cung cấp phương thức
@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
5

Ví dụ

@total_ordering
class Student:
    def _is_valid_operand(self, other):
        return (hasattr(other, "lastname") and
                hasattr(other, "firstname"))
    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))

Ghi chú

Mặc dù trình trang trí này giúp dễ dàng tạo các loại được sắp xếp hoàn toàn hoạt động tốt, nhưng nó phải trả giá bằng việc thực thi chậm hơn và dấu vết ngăn xếp phức tạp hơn cho các phương thức so sánh dẫn xuất. Nếu điểm chuẩn hiệu suất cho thấy đây là một nút cổ chai đối với một ứng dụng nhất định, thì việc triển khai tất cả sáu phương pháp so sánh phong phú thay vào đó có thể giúp tăng tốc độ dễ dàng

Ghi chú

Trình trang trí này không cố gắng ghi đè các phương thức đã được khai báo trong lớp hoặc các lớp cha của nó. Có nghĩa là nếu một siêu lớp định nghĩa một toán tử so sánh, thì total_ordering sẽ không triển khai lại nó, ngay cả khi phương thức ban đầu là trừu tượng

Mới trong phiên bản 3. 2

Đã thay đổi trong phiên bản 3. 4. Trả về NotImplemented từ chức năng so sánh cơ bản cho các loại không được nhận dạng hiện được hỗ trợ.

công cụ chức năng. một phần(func , / , *đối số , **từ khóa)

Trả về một cái mới mà khi được gọi sẽ hoạt động giống như func được gọi với các đối số vị trí đối số và đối số từ khóa từ khóa. Nếu nhiều đối số được cung cấp cho cuộc gọi, chúng sẽ được thêm vào args. Nếu các đối số từ khóa bổ sung được cung cấp, chúng sẽ mở rộng và ghi đè các từ khóa. Gần tương đương với

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

The được sử dụng cho ứng dụng hàm một phần "đóng băng" một số phần đối số và/hoặc từ khóa của hàm dẫn đến một đối tượng mới có chữ ký đơn giản hóa. Ví dụ: có thể được sử dụng để tạo một hàm có thể gọi được hoạt động giống như hàm trong đó đối số cơ sở mặc định là hai

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18

lớp công cụ chức năng. phương pháp một phần(func , / , *đối số , **từ khóa)

Trả về một bộ mô tả mới hoạt động giống như ngoại trừ việc nó được thiết kế để sử dụng làm định nghĩa phương thức thay vì có thể gọi trực tiếp

func phải là một hoặc có thể gọi được (các đối tượng có cả hai, giống như các hàm thông thường, được xử lý dưới dạng bộ mô tả)

Khi func là một bộ mô tả (chẳng hạn như một hàm Python thông thường, , ,

@total_ordering
class Student:
    def _is_valid_operand(self, other):
        return (hasattr(other, "lastname") and
                hasattr(other, "firstname"))
    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))
3 hoặc một phiên bản khác của ), các lệnh gọi tới
@total_ordering
class Student:
    def _is_valid_operand(self, other):
        return (hasattr(other, "lastname") and
                hasattr(other, "firstname"))
    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))
5 được ủy quyền cho bộ mô tả cơ bản và kết quả là một kết quả trả về thích hợp

Khi func không phải là bộ mô tả có thể gọi được, một phương thức ràng buộc thích hợp sẽ được tạo động. Điều này hoạt động giống như một hàm Python bình thường khi được sử dụng như một phương thức. đối số self sẽ được chèn làm đối số vị trí đầu tiên, ngay cả trước các đối số và từ khóa được cung cấp cho hàm tạo

Ví dụ

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
0

Mới trong phiên bản 3. 4

công cụ chức năng. reduce(chức năng , có thể lặp lại[ , trình khởi tạo])

Áp dụng chức năng của hai đối số tích lũy cho các mục có thể lặp lại, từ trái sang phải, để giảm khả năng lặp lại thành một giá trị duy nhất. Ví dụ,

@total_ordering
class Student:
    def _is_valid_operand(self, other):
        return (hasattr(other, "lastname") and
                hasattr(other, "firstname"))
    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))
7 tính toán
@total_ordering
class Student:
    def _is_valid_operand(self, other):
        return (hasattr(other, "lastname") and
                hasattr(other, "firstname"))
    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))
8. Đối số bên trái, x, là giá trị tích lũy và đối số bên phải, y, là giá trị cập nhật từ iterable. Nếu có bộ khởi tạo tùy chọn, nó sẽ được đặt trước các mục của có thể lặp lại trong phép tính và đóng vai trò là mặc định khi có thể lặp lại trống. Nếu trình khởi tạo không được cung cấp và iterable chỉ chứa một mục, thì mục đầu tiên được trả về

Gần tương đương với

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
1

Xem một trình vòng lặp mang lại tất cả các giá trị trung gian

@công cụ chức năng. duy nhất

Chuyển đổi một chức năng thành một

Để xác định một hàm chung, hãy trang trí nó bằng trình trang trí

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
0. Khi xác định hàm bằng cách sử dụng
def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
0, hãy lưu ý rằng việc gửi đi xảy ra trên loại đối số đầu tiên

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
2

Để thêm các triển khai quá tải vào hàm, hãy sử dụng thuộc tính

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
2 của hàm chung, thuộc tính này có thể được sử dụng làm công cụ trang trí. Đối với các hàm được chú thích bằng các loại, trình trang trí sẽ tự động suy ra loại đối số đầu tiên

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
3

và cũng có thể được sử dụng

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
4

Đối với mã không sử dụng chú thích kiểu, đối số kiểu thích hợp có thể được truyền rõ ràng cho chính trình trang trí

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
5

Để kích hoạt các chức năng đăng ký và có sẵn, thuộc tính

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
2 cũng có thể được sử dụng ở dạng chức năng

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
6

Thuộc tính

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
2 trả về hàm chưa trang trí. Điều này cho phép xếp chồng trang trí, và tạo các bài kiểm tra đơn vị cho từng biến thể một cách độc lập

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
7

Khi được gọi, hàm chung gửi đi loại đối số đầu tiên

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
8

Khi không có triển khai đã đăng ký cho một loại cụ thể, thứ tự giải quyết phương thức của nó được sử dụng để tìm triển khai chung hơn. Chức năng ban đầu được trang trí bằng

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
0 được đăng ký cho loại cơ sở, có nghĩa là nó được sử dụng nếu không tìm thấy triển khai tốt hơn

Nếu một triển khai được đăng ký cho một lớp con ảo của lớp cơ sở sẽ được gửi đến triển khai đó

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
9

Để kiểm tra xem chức năng chung sẽ chọn triển khai nào cho một loại nhất định, hãy sử dụng thuộc tính

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
0

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)
0

Để truy cập tất cả các triển khai đã đăng ký, hãy sử dụng thuộc tính chỉ đọc

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
1

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)
1

Mới trong phiên bản 3. 4

Đã thay đổi trong phiên bản 3. 7. Thuộc tính

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
2 hiện hỗ trợ sử dụng chú thích loại.

Đã thay đổi trong phiên bản 3. 11. Thuộc tính

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc
2 hiện hỗ trợ và dưới dạng chú thích loại.

lớp công cụ chức năng. singledispatchmethod(chức năng)

Biến một phương thức thành một

Để xác định một phương thức chung, hãy trang trí nó bằng trình trang trí

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
6. Khi xác định một hàm bằng cách sử dụng
>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
6, lưu ý rằng việc gửi đi xảy ra trên loại đối số không phải là ngã hoặc không phải cls đầu tiên

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)
2

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
6 hỗ trợ lồng ghép với các bộ trang trí khác, chẳng hạn như. Lưu ý rằng để cho phép
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
00,
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
01 phải là trang trí bên ngoài nhất. Đây là lớp
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
02 với các phương thức
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
03 được liên kết với lớp, chứ không phải là một thể hiện của lớp

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)
3

Mẫu tương tự có thể được sử dụng cho các trang trí tương tự khác. , , và những người khác

Mới trong phiên bản 3. 8

công cụ chức năng. update_wrapper(trình bao bọc , được bao bọc , đã chỉ định=WRAPPER_ASSIGNMENTS , đã cập nhật=WRAPPER_UPDATES)

Cập nhật chức năng bao bọc để trông giống như chức năng bao bọc. Các đối số tùy chọn là các bộ để chỉ định thuộc tính nào của hàm ban đầu được gán trực tiếp cho các thuộc tính phù hợp trên hàm bao bọc và thuộc tính nào của hàm bao bọc được cập nhật với các thuộc tính tương ứng từ hàm ban đầu. Các giá trị mặc định cho các đối số này là hằng số cấp mô-đun

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
06 (gán cho hàm bao bọc là
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
07,
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
08,
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
09,
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
10 và
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
11, chuỗi tài liệu) và
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
12 (cập nhật hàm bao bọc là
sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order
3, i. e. từ điển ví dụ)

Để cho phép truy cập vào chức năng ban đầu để xem xét nội tâm và các mục đích khác (e. g. bỏ qua trình trang trí bộ nhớ đệm chẳng hạn như ), chức năng này sẽ tự động thêm thuộc tính

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
8 vào trình bao bọc đề cập đến chức năng được bao bọc

Mục đích sử dụng chính cho chức năng này là trong các chức năng bao bọc chức năng được trang trí và trả về trình bao bọc. Nếu chức năng trình bao bọc không được cập nhật, siêu dữ liệu của hàm được trả về sẽ phản ánh định nghĩa trình bao bọc thay vì định nghĩa hàm ban đầu, điều này thường ít hữu ích hơn

có thể được sử dụng với các cuộc gọi khác với chức năng. Bất kỳ thuộc tính nào có tên được gán hoặc cập nhật bị thiếu trong đối tượng được bao bọc đều bị bỏ qua (i. e. chức năng này sẽ không cố đặt chúng trên chức năng trình bao bọc). vẫn được nâng lên nếu bản thân chức năng bao bọc thiếu bất kỳ thuộc tính nào có tên trong bản cập nhật

Mới trong phiên bản 3. 2. Tự động thêm thuộc tính

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
8.

Mới trong phiên bản 3. 2. Sao chép thuộc tính

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
10 theo mặc định.

Đã thay đổi trong phiên bản 3. 2. Các thuộc tính bị thiếu không còn kích hoạt.

Đã thay đổi trong phiên bản 3. 4. Thuộc tính

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
8 giờ đây luôn đề cập đến hàm được bao bọc, ngay cả khi hàm đó đã xác định thuộc tính
@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://peps.python.org/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)
8. (xem bpo-17482)

@công cụ chức năng. kết thúc(được bao bọc , đã chỉ định=WRAPPER_ASSIGNMENTS , đã cập nhật=WRAPPER_UPDATES)

Đây là một chức năng tiện lợi để gọi như một công cụ trang trí chức năng khi xác định chức năng bao bọc. Nó tương đương với

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
24. Ví dụ

class DataSet:
    def __init__(self, sequence_of_numbers):
        self._data = sequence_of_numbers

    @property
    @cache
    def stdev(self):
        return statistics.stdev(self._data)
4

Nếu không sử dụng nhà máy trang trí này, tên của hàm ví dụ sẽ là

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
25 và chuỗi tài liệu của bản gốc
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
26 sẽ bị mất

Các đối tượng

các đối tượng là các đối tượng có thể gọi được tạo bởi. Chúng có ba thuộc tính chỉ đọc

một phần. chức năng

Một đối tượng hoặc chức năng có thể gọi được. Các cuộc gọi đến đối tượng sẽ được chuyển tiếp với các đối số và từ khóa mới

một phần. đối số

Các đối số vị trí ngoài cùng bên trái sẽ được thêm vào trước các đối số vị trí được cung cấp cho lệnh gọi đối tượng

một phần. từ khóa

Các đối số từ khóa sẽ được cung cấp khi đối tượng được gọi

các đối tượng giống như các đối tượng

class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
35 ở chỗ chúng có thể gọi được, có thể tham chiếu yếu và có thể có các thuộc tính. Có một số khác biệt quan trọng. Chẳng hạn, các thuộc tính và
class DataSet:

    def __init__(self, sequence_of_numbers):
        self._data = tuple(sequence_of_numbers)

    @cached_property
    def stdev(self):
        return statistics.stdev(self._data)
11 không được tạo tự động. Ngoài ra, các đối tượng được định nghĩa trong các lớp hoạt động giống như các phương thức tĩnh và không chuyển đổi thành các phương thức bị ràng buộc trong quá trình tra cứu thuộc tính thể hiện

một ví dụ chức năng một phần là gì?

Định nghĩa. Một chức năng không được xác định cho một số đầu vào thuộc loại phù hợp, nghĩa là đối với một số miền. Chẳng hạn, phép chia là một hàm bộ phận vì phép chia cho 0 không được xác định (trên Thực tế) .

Chức năng một phần trong lập trình là gì?

Trong khoa học máy tính, ứng dụng từng phần (hoặc ứng dụng chức năng từng phần) đề cập đến quá trình cố định một số đối số cho một hàm, tạo ra một hàm khác có mức độ nhỏ hơn. Given a function , we might fix (or 'bind') the first argument, producing a function of type .

Lớp một phần trong Python là gì?

Từ khóa partial cho phép chia định nghĩa lớp thành các phần khác nhau trong cùng một không gian tên, phần này sẽ được kết hợp khi ứng dụng được biên dịch . Để sử dụng tính năng này, mỗi phần phải. Sử dụng từ khóa một phần. Có sẵn tại thời điểm biên dịch.

Sự khác biệt giữa đóng cửa và một phần trong Python là gì?

Đóng là khi bạn kết hợp một số trạng thái hoặc ngữ cảnh với mã để sau này bạn có thể thực thi mã đó được liên kết với các giá trị trạng thái đó ngay cả khi nguồn gốc của các giá trị hiện đã biến mất. Ứng dụng một phần là khi bạn liên kết một hoặc nhiều (nhưng không phải tất cả) đối số của hàm với giá trị bằng cách sử dụng bao đóng