1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Decorator function xử lý ảnh

11 5 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 11
Dung lượng 32,88 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

DECORATOR FUNCTION Decorator function, một trong những khái niệm phức tạp nhất và hữu dụng nhất trong lập trình Python Nội dung Decorator trong Python là gì và tác dụng Cách định nghĩa c.

Trang 1

DECORATOR FUNCTION

Decorator functon, m t trong nhưng khai ni m phưc tap nhât va hưu dung nhât ô ê trong l p trinh Python N i dung:â ô

• Decorator trong Python la gi va tac dung

• Cach định nghĩa cac decorator

• Ví du

• Viết code tốt hơn bằng decorator

Giới thiệu

1

2

3

@decorator

def functon_to_decorate():

pass

Tiền tố @ Cac decorator đặc biệt hưu ích trong việc giư code không bị lặp lại, va

chúng lam điều đó nhưng đồng thời cũng cải thiện khả năng đọc của code vi decorator chỉ la cac ham Python

01

02

03

04

05

06

07

08

09

def x_plus_2(x):

return x + 2

print(x_plus_2(2)) # 2 + 2 ==4

def x_squared(x):

return x * x

print(x_squared(3)) # 3 ^ 2 == 9

# Let's compose the two functons for x=2

Trang 2

11

12

13

14

15

16

print(x_squared(x_plus_2(2))) # (2 + 2) ^ 2 == 16

print(x_squared(x_plus_2(3))) # (3 + 2) ^ 2 == 25

print(x_squared(x_plus_2(4))) # (4 + 2) ^ 2 == 36

Tao ra một ham khac, ham x_plus_2_squared

1 x_squared(x_plus_2) # TypeError: unsupported operand type(s) for *:

'functon' and 'functon'

Không thể tổ hợp cac ham bằng cach nay bởi vi cả hai ham đều nhận cac con số như la cac đối số:

1

2

3

4

5

6

# Let's now create a proper functon compositon without actually applying the functon

x_plus_2_squared = lambda x: x_squared(x_plus_2(x))

print(x_plus_2_squared(2)) # (2 + 2) ^ 2 == 16

print(x_plus_2_squared(3)) # (3 + 2) ^ 2 == 25

print(x_plus_2_squared(4)) # (4 + 2) ^ 2 == 36

Định nghĩa lai cach ham x_squared lam việc:

1. Châp nhận một ham như một đối số

2. Trả về một ham khac

Đ t tên tên ham có thể tai tổ hợp củaă x_squared đơn giản la squared

Trang 3

2

3

4

5

6

def squared(func):

return lambda x: func(x) * func(x)

print(squared(x_plus_2)(2)) # (2 + 2) ^ 2 == 16

print(squared(x_plus_2)(3)) # (3 + 2) ^ 2 == 25

print(squared(x_plus_2)(4)) # (4 + 2) ^ 2 == 36

Bây giờ có thể sử dung nó với bât kỳ ham nao khac Dưới đây la một số ví du: 1

2

3

4

5

6

7

8

def x_plus_3(x):

return x + 3

def x_tmes_2(x):

return x * 2

print(squared(x_plus_3)(2)) # (2 + 3) ^ 2 == 25

print(squared(x_tmes_2)(2)) # (2 * 2) ^ 2 == 16

Có thể nói rằng ham squared decorate cac ham x_plus_2, x_plus_3 va x_tmes_2 1

2

x_plus_2 = squared(x_plus_2) # We decorated x_plus_2 with squared

print(x_plus_2(2)) # x_plus_2 now returns the decorated squared result: (2 + 2) ^ 2

01

02

03

def x_plus_2(x):

return x + 2

Trang 4

05

06

07

08

09

10

x_plus_2 = squared(x_plus_2)

# ^ This is completely equivalent with:

@squared

def x_plus_2(x):

return x + 2

Ký hiệu @ la một hinh thưc cú phap dễ đọc:

01

02

03

04

05

06

07

08

09

10

11

12

@squared

def x_tmes_3(x):

return 3 * x

print(x_tmes_3(2)) # (3 * 2) ^ 2 = 36

# It might be a bit confusing, but by decoratng it with squared, x_tmes_3 became in fact (3 * x) * (3 * x)

@squared

def x_minus_1(x):

return x - 1

print(x_minus_1(3)) # (3 - 1) ^ 2 = 4

Xây dựng Decorator

Trang 5

Một decorator la một ham nhận một ham như la một đối số va trả về một ham khac, định nghĩa decorator:

1

2

3

def decorator(functon_to_decorate):

#

return decorated_functon

Có thể định nghĩa cac ham bên trong cac ham khac Trong hầu hết cac trường hợp, decorated_functon sẽ được định nghĩa bên trong decorator

1

2

3

4

def decorator(functon_to_decorate):

def decorated_functon(*args, **kwargs):

# Since we decorate `functon_to_decorate`, we should use it

somewhere inside here

return decorated_functon

01

02

03

04

05

06

07

08

09

10

11

import pytz

from datetme import datetme

def to_utc(functon_to_decorate):

def decorated_functon():

# Get the result of functon_to_decorate and transform the result to UTC return functon_to_decorate().astmezone(pytz.utc)

return decorated_functon

@to_utc

def package_pickup_tme():

Trang 6

13

14

15

16

17

18

19

20

21

22

23

""" This can come from a database or from an API """

tz = pytz.tmezone('US/Pacific')

return tz.localize(datetme(2017, 8, 2, 12, 30, 0, 0))

@to_utc

def package_delivery_tme():

""" This can come from a database or from an API """

tz = pytz.tmezone('US/Eastern')

return tz.localize(datetme(2017, 8, 2, 12, 30, 0, 0)) # What a coincidence, same tme different tmezone!

print("PICKUP: ", package_pickup_tme()) # '2017-08-02 19:30:00+00:00' print("DELIVERY: ", package_delivery_tme()) # '2017-08-02 16:30:00+00:00'

Ví dụ Thực tế

Một trường hợp sử dung rât phổ biến va rât kinh điển khac đối với decorator la lưu cache kết quả của một ham:

01

02

03

04

05

06

07

08

import tme

def cached(functon_to_decorate):

_cache = {} # Where we keep the results

def decorated_functon(*args):

start_tme = tme.tme()

print('_cache:', _cache)

if args not in _cache:

Trang 7

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

_cache[args] = functon_to_decorate(*args) # Perform the computaton and store it in cache

print('Compute tme: %ss' % round(tme.tme() - start_tme, 2))

return _cache[args]

return decorated_functon

@cached

def complex_computaton(x, y):

print('Processing ')

tme.sleep(2)

return x + y

print(complex_computaton(1, 2)) # 3, Performing the expensive operaton print(complex_computaton(1, 2)) # 3, SKIP performing the expensive

operaton

print(complex_computaton(4, 5)) # 9, Performing the expensive operaton print(complex_computaton(4, 5)) # 9, SKIP performing the expensive

operaton

print(complex_computaton(1, 2)) # 3, SKIP performing the expensive

operaton

Nếu ban nhin sơ qua code, ban có thể thây khó chịu Decorator không thể sử dung lai được! Nếu chúng ta decorate một ham khac (gọi

la another_complex_computaton) va gọi nó với cac tham số tương tự thi chúng ta

sẽ nhận được cac kết quả được cache từ ham complex_computaton Điều nay sẽ không xảy ra Decorator có thể sử dung lai va đây la lý do:

Trang 8

2

3

4

5

6

7

8

9

@cached

def another_complex_computaton(x, y):

print('Processing ')

tme.sleep(2)

return x * y

print(another_complex_computaton(1, 2)) # 2, Performing the expensive operaton

print(another_complex_computaton(1, 2)) # 2, SKIP performing the expensive operaton

print(another_complex_computaton(1, 2)) # 2, SKIP performing the expensive operaton

Ham chached được gọi một lần cho mỗi ham ma nó decorate, do đó, một

biến _cache khac được khởi tao mỗi lần va tồn tai trong ngư cảnh đó Hãy thử điều đó:

1

2

print(complex_computaton(10, 20)) # -> 30

print(another_complex_computaton(10, 20)) # -> 200

Decorator trong Thực tế

Decorator ma chúng ta vừa mớ viết, như ban có thể nhận thây, rât hưu ích Nó hưu ích đến nỗi một phiên bản phưc tap va manh mẽ hơn đã tồn tai trong mô

đun functools têu chuẩn Nó được đặt tên la lru_cache LRU la viết tắt của Least

Recently Used, một ky thu t cahe.â

01

02

03

from functools import lru_cache

@lru_cache()

Trang 9

05

06

07

08

09

10

11

12

13

def complex_computaton(x, y):

print('Processing ')

tme.sleep(2)

return x + y

print(complex_computaton(1, 2)) # Processing 3

print(complex_computaton(1, 2)) # 3

print(complex_computaton(2, 3)) # Processing 5

print(complex_computaton(1, 2)) # 3

print(complex_computaton(2, 3)) # 5

Một trong nhưng trường hợp sử dung decorator la trong framework Flask Nó thi gọn gang, đó la đoan code điều đầu tên ban nhin thây trên trang web Flask Đây

la đoan code đó:

01

02

03

04

05

06

07

08

09

10

from flask import Flask

app = Flask( name )

@app.route("/")

def hello():

return "Hello World!"

if name == " main ":

app.run()

Trang 10

Decorator app.route gan ham hello lam trinh xử lý yêu cầu cho tuyến "/" Thật sự đơn giản

Một cach sử dung decorator gọn gang khac la bên trong Django Thông thường, cac ưng dung web có hai kiểu trang:

1. cac trang ban có thể xem ma không cần chưng thực (trang chủ, trang

landing, bai blog, đăng nhập, đăng ký)

2. cac trang ban cần phải được chưng thực để xem (cai đặt tểu sử, hộp thư đến, bảng điều khiển)

Nếu ban thử xem một kiểu trang thư hai, ban thường sẽ được chuyển hướng đến một trang đăng nhập Dưới đây la cach thực hiện điều đó trong Django:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

from django.http import HttpResponse

from django.contrib.auth.decorators import login_required

# Public Pages

def home(request):

return HttpResponse("<b>Home</b>")

def landing(request):

return HttpResponse("<b>Landing</b>")

# Authentcated Pages

@login_required(login_url='/login')

def dashboard(request):

return HttpResponse("<b>Dashboard</b>")

Trang 11

18

19

20

@login_required(login_url='/login')

def profile_settings(request):

return HttpResponse("<b>Profile Settings</b>")

Quan sat xem cac chế độ view riêng tư gọn gang như thế nao được đanh dâu bằng login_required Khi xem qua code, nó rât rõ rang đối với người đọc ma cac trang yêu cầu người dùng đăng nhập va nhưng trang không yêu cầu

Phần tóm tắt

Tôi hy vọng ban đã có một buổi học thú vị về decorator bởi vi chúng đai diện cho một tính năng rât gọn gang trong Python Dưới đây la một số điều cần nhớ:

• Sử dung va thiết kế decorator đúng cach có thể lam cho code của ban trở nên tốt hơn, sach sẽ hơn va đẹp hơn

• Sử dung decorator có thể giúp ban DRY code—di chuyển cac code giống nhau từ bên trong cac ham vao decorator

• Khi ban sử dung cac decorator nhiều hơn, ban sẽ thây nhưng cach tốt hơn, phưc tap hơn để sử dung chúng

Ngày đăng: 11/09/2022, 23:00

w