Python-Function

Trong phần này chúng ta tìm hiểu function trong Python.

Định nghĩa function

Function là một block source code được sử dụng để thực hiện một chức năng cụ thể. Ưu điểm của việc sử dụng function là:
– Giảm code lặp lại.
– Phân chia các vấn đề phức tạp thành vấn đề đơn giản hơn.
– Tái sử dụng code
– Ẩn thông tin.

Function trong Python là first-class citizens. Có nghĩa là function có trạng thái bình đẳng với các objects khác trong Python. Function có thể được gán cho biến, lưu trữ trong collection (list, tuple,…) hoặc truyền như đối số. Điều này mang lại tính linh hoạt cho Python.

Function type

Có 2 loại function: built-in và user-defined function.
– Built-in function là function được tích hợp sẵn trong ngôn ngữ Python như: len(), dir() hoặc abs()
– User-defined function là function do user tự define với keyword def

Tạo function

Function được tạo với keyword def. Câu lệnh trong block trong function phải thụt lùi 1 tab hoặc space

def function():
    pass

Theo sau keyword def là tên function đi kèm với ngoặc tròn () và dấu :. Câu lệnh trong function được lùi vào 1 tab hoặc spaces.
Hàm được thực thi khi chúng ta gọi hàm.
Để gọi hàm chúng ta viết tên function + dấu ngoặc tròn như sau:
function()

Ví dụ 1: Khai báo và gọi hàm

"""
The test.py script shows how to work with
functions in Python.
Author: VietVH
vncoding, 2022
"""

def show_module_name():
    print(__doc__)


def get_module_file():
    return __file__


a = show_module_name()
b = get_module_file()

print(a, b)
"""
The test.py script shows how to work with
functions in Python.
Author: VietVH
vncoding, 2022
"""

String này được gọi là documentation string. File test.py được gọi mà module.

def show_module_name():
    print(__doc__)

Định nghĩa hàm show_module_name(),
– Hàm này in ra thuộc tính __doc__ chứa documentation string ở trên.
– Hàm này không trả về giá trị, tức là trả về None

def get_module_file():
    return __file__

Định nghĩa hàm get_module_file(), hàm này trả về thuộc tính __file__ (tên file script test.py)

a = show_module_name()
b = get_module_file()

Đây là lời gọi 2 hàm, giá trị trả về lần lượt được lưu vào biến a và b.

Kết quả:
C:\Users\Dell>python test.py

The test.py script shows how to work with
functions in Python.
Author: VietVH
vncoding, 2022

None test.py

Phải định nghĩa hàm trước khi gọi hàm. Nếu không trình thông dịch sẽ thông báo lỗi NameError.
Ví dụ 2: Định nghĩa hàm sau khi gọi hàm

def f1():
    print("f1()")


f1()
f2()


def f2():
    print("f2()")

– Khi gọi hàm f1(): in ra string “f1()”
– Khi gọi hàm f1(): trình thông dịch báo lỗi NameError

Kết quả:
C:\Users\Dell>python test.py
f1()
Traceback (most recent call last):
File “test.py”, line 6, in
f2()
NameError: name ‘f2’ is not defined

Định nghĩa function ở đâu?

Hàm có thể được định nghĩa trong module, class, hoặc trong 1 hàm khác. Hàm được định nghĩa trong class được gọi là phương thức.
Ví dụ 3:

class Some():

    @staticmethod
    def f():
        print("f() method")


def f():
    print("f() function")


def g():
    def f():
        print("f() inner function")
    f()


Some.f()
f()
g()

Trong ví dụ này, chúng ta định nghĩa hàm ở các vị trí khác nhau.

def f():
    print("f() method")

Định nghĩa phương thức static f() trong class Some

def f():
    print("f() function")

Định nghĩa hàm trong module test.py

def g():
    def f():
        print("f() inner function")
    f()

Định nghĩa function f() trong function g(). Gọi là inner function.
Function f() định nghĩa trong function g(), chỉ được gọi trong function g().

Some.f()
f()
g()

Với method static được gọi bởi tên class và toán tử dot (.) sau đó là tên phương thức.

Kết quả:

C:\Users\Dell>python test.py
f() method
f() function
f() inner function

Function Python là object

Function trong Python là các object. Function có thể được thao tác như các object khác trong Python. Tính chất này không giống các ngôn ngữ OOP khác (Java, C#)

Ví dụ 4: Minh họa function có các thuộc tính của object

def f():
    """This function prints a message """

    print("Today it is a cloudy day")


print(isinstance(f, object))
print(id(f))

print(f.__doc__)
print(f.__name__)
def f():
    """This function prints a message """

    print("Today it is a cloudy day")

Định nghĩa function f() gồm có documentation string và in string “Today it is a cloudy day” ra màn hình.

print(isinstance(f, object))

Hàm isinstance() kiểm tra liệu rằng function f có phải là instance của object hay không?

print(id(f))

Mỗi object trong Python có một id duy nhất. Hàm id(f) trả về id của object function f().

print(f.__doc__)
print(f.__name__)

Object có nhiều thuộc tính. Chúng ta in ra 2 thuộc tính __doc__ và __name__

Kết quả:
C:\Users\Dell>python test.py
True
2095105556960
This function prints a message
f

Function có thể lưu trong collection (list, tuple) và truyền function vào function khác
Ví dụ 5: Function có thể lưu trong collection (list, tuple) và truyền vào function khác

def f():
    pass

def g():
    pass

def h(f):
    print(id(f))

a = (f, g, h)

for i in a:
    print(i)

h(f)
h(g)

Trong ví dụ này, chúng ta định nghĩa 3 function và lưu vào trong tuple, truyền function vào function khác.

a = (f, g, h)

for i in a:
    print(i)

Lưu function f, g, h vào tuple và duyệt ở vòng lặp for.

h(f)
h(g)

Chúng tôi truyền f và g vào function h.

Kết quả:
C:\Users\Dell>python test.py



1914540507616
1914541144536

Ba loại function trong Python

Có thể chia thành 3 loại function.
– Function mặc định của Python, có thể gọi bất cứ khi nào trong source code.
– Function được đặt trong external module
– Function được định nghĩa bởi keyword def

Ví dụ 6: Minh họa 3 loại function trong Python

from math import sqrt

def cube(x):
    return x * x * x

print(abs(-1))
print(cube(9))
print(sqrt(81))
from math import sqrt

Function sqrt được import từ module math

def cube(x):
    return x * x * x

Hàm tự định nghĩa với keyword def

print(abs(-1))

Hàm abs() là built-in function của Python, gọi hàm mà không cần import.

Kết quả:
C:\Users\Dell>python test.py
1
729
9.0

Keyword return

Function có thể trả về hoặc không trả về giá trị. Sử dụng keyword return nếu function trả về giá trị. Nếu không có keyword return, function trả về None.

Ví dụ 7: Minh họa keyword return

def show_message(msg):
    print(msg)

def cube(x):
    return x * x * x

x = cube(3)
print(x)

show_message("Computation finished.")
print(show_message("Ready."))

Trong ví dụ này, chúng ta định nghĩa 2 function: 1 function trả về giá trị, còn 1 function không trả về giá trị.

def show_message(msg):
    print(msg)

Function show_message() không trả về giá trị, chỉ in string ra màn hình console.

def cube(x):
    return x * x * x

Function cube() trả về giá trị (x * x * x)

x = cube(3)

Đây là lệnh gọi hàm cube() với tham số truyền vào là 3, giá trị trả về được lưu vào biến x.

show_message("Computation finished.")

Gọi hàm show_message() với tham số truyền vào là string “Computation finished.”. Hàm này không trả về giá trị.

print(show_message("Ready."))

Dòng code này in ra 2 dòng kết quả:
– Thứ 1 là messsage “Ready.” được in ra màn hình console bởi hàm show_message().
– Thứ 2 là giá trị None, giá trị None được ngầm định trả về bởi function không có lệnh return.

Kết quả:
C:\Users\Dell>python test.py
27
Computation finished.
Ready.
None

Ví dụ 8: Hàm trả về nhiều giá trị

n = [1, 2, 3, 4, 5]

def stats(x):

    _mx = max(x)
    _mn = min(x)
    _ln = len(x)
    _sm = sum(x)

    return _mx, _mn, _ln, _sm


mx, mn, ln, sm = stats(n)

print(stats(n))
print(mx, mn, ln, sm)

Định nghĩa hàm stats() trả về 4 giá trị (max/min/len/sum của list n)

return _mx, _mn, _ln, _sm

Keyword return trả về 3 giá trị. Các giá trị được phân tách nhau bởi dấu phẩy. Về bản chất, là hàm trả về tuple gồm 4 giá trị. Chúng ta cũng có thể trả về list thay vì trả về tuple.

Kết quả:
C:\Users\Dell>python test.py
(5, 1, 5, 15)
5 1 5 15

Function redefinition

Python là ngôn ngữ động, có thể redefine function đã được define trước đó

Ví dụ 9: Redefine function

from time import gmtime, strftime

def show_message(msg):
    print(msg)

show_message("Ready.")

def show_message(msg):
    print(strftime("%H:%M:%S", gmtime()))
    print(msg)

show_message("Processing.")

Trong ví dụ này, chúng ta define hàm show_message(). Sau đó chúng ta redefine function đó

from time import gmtime, strftime

Import function gmtime và strftime từ module time để tính thời gian.

def show_message(msg):
    print(msg)

show_message("Ready.")

Define hàm show_message() lần đầu, in ra màn hình message.

def show_message(msg):
    print(strftime("%H:%M:%S", gmtime()))
    print(msg)

Redefine hàm show_message(), hiển thị message thời gian được lấy từ hàm gmtime().

Kết quả:
C:\Users\Dell>python test.py
Ready.
05:32:05
Processing.

Function arguments

Hầu hết function nhận giá trị truyền vào gọi là argument (đối số). Argument là giá trị được truyền vào function. Các function sử dụng các giá trị truyền vào để tính toán và trả về giá trị.

Ví dụ 10: Truyền argument cho function

def C2F(c):
    return c * 9/5 + 32

print(C2F(100))
print(C2F(0))
print(C2F(30))

Hàm C2F() convert từ nhiệt đô C sang độ F. Tham số truyền vào là nhiệt độ C.

Kết quả:
C:\Users\Dell>python test.py
212.0
32.0
86.0

Ví dụ 11: Tham số mặc định cho hàm số

def power(x, y=2):
    r = 1

    for i in range(y):
        r = r * x
    return r

print(power(3))
print(power(3, 3))
print(power(5, 5))

Định nghĩa hàm power với 2 tham số, tham số thứ 2 được set default y=2. Nếu trường hợp gọi hàm power() không truyền vào tham số thứ 2, thì y = 2 sẽ được sử dụng.

print(power(3))

Gọi hàm power(3) tương đương với power(3,2).

Kết quả:
C:\Users\Dell>python test.py
9
27
3125

Hàm trong Python có thể chỉ định argument kèm với keyword. Điều này có nghĩa là khi gọi hàm, chúng ta có thể chị định cả keyword và giá trị. Khi chúng ta có nhiều argument và chúng được sử dụng không có keyword đi kèm, thứ tự truyền argument là rất quan trọng. Nêu chúng ta truyền cho hàm 3 argument (name, age hoặc sex) không kèm với keyword, thì không để thay đổi được thứ tự giữa 3 argument. Nếu chúng ta sử dụng keyword, chúng ta có thể thay đổi thứ tự truyền argument cho hàm.

Ví dụ 12: Truyền nhiều argument cho hàm

def display(name, age, sex):

    print("Name: ", name)
    print("Age: ", age)
    print("Sex: ", sex)


display("Lary", 43, "M")
display("Joan", 24, "F")

Trong ví dụ này, chúng ta truyền cho hàm display() 3 argument. Việc truyền argument đúng theo thứ tự rất quan trọng, nếu truyền sai thứ tự, sẽ cho kết quả sai.

Kết quả:
C:\Users\Dell>python test.py
Name: Lary
Age: 43
Sex: M
Name: Joan
Age: 24
Sex: F

Để tránh việc truyền nhầm thứ tự argument, chúng ta truyền argument đi kèm với keyword.
Ví dụ 13: Truyền argument đi kèm với keyword

def display(name, age, sex):

    print("Name: ", name)
    print("Age: ", age)
    print("Sex: ", sex)

display(age=43, name="Lary", sex="M")
display(name="Joan", age=24, sex="F")

Trong ví dụ này, chúng ta truyền argument đi kèm với keyword và có thể thay đổi thứ tự truyền argument.
Chú ý: Chúng ta không thể sử dụng non-keyword argument đi sau keyword argument. Chương trình thông dịch báo lỗi.

display("Joan", sex="F", age=24)

Lời gọi hàm không vi phạm rule.

display(age=24, name="Joan", "F")

Lời gọi hàm vi phạm rule vì non-keyword argument “F” đi sau keyword argument name=”Joan”

Kết quả
C:\Users\Dell>python test.py
Name: Lary
Age: 43
Sex: M
Name: Joan
Age: 24
Sex: F

Chúng ta có thể truyền tùy ý số lượng argument cho hàm
Ví dụ 14: Truyền tùy ý số lượng argument cho hàm

def do_sum(*args):
    """Function returns the sum
of all values"""

    r = 0

    for i in args:
        r += i

    return r


print(do_sum.__doc__)
print(do_sum(1, 2, 3))
print(do_sum(1, 2, 3, 4, 5))

Chúng ta sử dụng toán tử * để ám chỉ rằng hàm có thể nhận tùy ý số lượng argument. Hàm do_sum() trả về tổng của các argument. Chuỗi “””Function returns the sum of all values””” được gọi là function documentation string, được sử dụng để mô tả thêm về function.

Kết quả:
C:\Users\Dell>python test.py
Function returns the sum
of all values
6
15

Chúng ta có thể sử dụng toán tử ** trong hàm. Hàm sẽ nhận dictionary. Dictionary có độ dài tùy ý. Chúng ta có thể parse dictionary như cách đã giới thiệu ở bài trước đó.
Ví dụ 15: Sử dụng toán tử ** để truyền vào nhiều argument

def display(**details):

    for i in details:
        print(f"{i}: {details[i]}")

display(name="Larry", age=43, sex="M")

Trong ví dụ này, chúng ta có thể truyền vào số lượng argument key-value tùy ý, hàm có thể xử lí được hết.

Kết quả:
C:\Users\Dell>python test.py
name: Larry
age: 43
sex: M

Truyền tham chiếu cho hàm

Truyền tham số theo kiểu tham chiếu cho hàm. Một số ngôn ngữ lập trình truyền bản copy object cho hàm. Truyền tham chiếu object có 2 điểm quan trọng:
1. Tốc độ xử lí nhanh hơn nếu truyền theo kiểu tham chiếu
2. Phép toán modify trực tiếp lên tham số truyền vào => thay đổi giá trị của tham số truyền vào.

Ví dụ 16: Truyền tham chiếu cho hàm

n = [1, 2, 3, 4, 5]

print("Original list:", n)

def f(x):

    x.pop()
    x.pop()
    x.insert(0, 0)
    print("Inside f():", x)

f(n)

print("After function call:", n)

Trong ví dụ này, chúng ta truyền vào cho hàm f() list số nguyên. Trong function f() modify trực tiếp list n, giá trị list n thay đổi

def f(x):

    x.pop()
    x.pop()
    x.insert(0, 0)
    print("Inside f():", x)

Trong thêm hàm f() modify trực tiếp lên list n. Trong nhiều ngôn ngữ lập trình, các hàm sẽ thao tác trên bản copy của tham số truyền vào.

Kết quả:
C:\Users\Dell>python test.py
Original list: [1, 2, 3, 4, 5] Inside f(): [0, 1, 2, 3] After function call: [0, 1, 2, 3]

Biến global và biến local

Tiếp theo, chúng ta discuss về cách dùng biến trong Python.
Ví dụ 17: Sử dụng biến local trong Python

name = "Jack"

def f():
    name = "Robert"
    print("Within function", name)

print("Outside function", name)
f()

Biến trong thân hàm gọi là biến local. Nó chỉ valid trong thân hàm.

Kết quả:
C:\Users\Dell>python test.py
Outside function Jack
Within function Robert

Ví dụ 18: Sử dụng biến global trong Python

name = "Jack"

def f():
    print("Within function", name)

print("Outside function", name)
f()

Biến name là biến global dùng được cả trong và ngoài hàm.

Kết quả:
C:\Users\Dell>python test.py
Outside function Jack
Within function Jack

Nếu chúng ta muốn thay đổi giá trị biên global trong hàm, chúng ta phải sử dụng keyword global
Ví dụ 19: Thay đổi giá trị biến global trong hàm

name = "Jack"

def f():
    global name
    name = "Robert"
    print("Within function", name)


print("Outside function", name)
f()
print("Outside function", name)

Trong ví dụ này, chúng ta có thể thay đổi giá trị biến global name trong hàm f() với keyword global.

Kết quả:
C:\Users\Dell>python test.py
Outside function Jack
Within function Robert
Outside function Robert

Anonymous function

Hàm anonymous không có tên function. Chúng ta có thể tạo hàm anonymous với keyword lambda. Hàm anonymous còn được gọi là function lambda.

Lambda function bị giới hạn trong 1 biểu thức đơn.
Ví dụ 20: Lambda function

y = 6

z = lambda x: x * y
print(z(8))

Đây là ví dụ đơn giản về lambda function.

z = lambda x: x * y

Keyword lambda tạo anonymous function. x là tham số truyền vào lambda function. Sau tham số truyền vào là dấu hai chấm. Tiếp theo là biểu thức toán được thực thi khi gọi lambda function. Lambda function được gán cho biến z.

print(z(8))

Khi lambda function được gọi. Số 8 được truyền vào anonymous function và trả về 48.
Chú ý: z không phải là tên function. z là biến nhận giá trị biểu thức trong lambda function.

Lambda function có thể kết hợp với map hoặc filter function
Ví dụ 21: Sử dụng lambda function kết hợp với map

cs = [-10, 0, 15, 30, 40]

ft = map(lambda t: (9.0/5)*t + 32, cs)
print(list(ft))

Trong ví dụ này, chúng ta có 1 list giá trị nhiệt độ C. Chúng ta tạo list mới gồm có nhiệt độ F.

ft = map(lambda t: (9.0/5)*t + 32, cs)

map() function apply anonymous function cho mỗi phần tử của list cs. Nó trả về iterable nhiệt độ F

Kết quả:
C:\Users\Dell>python test.py
[14.0, 32.0, 59.0, 86.0, 104.0]

Be the first to comment

Leave a Reply