updated July 05, 2024213 views

Cho đến nay, các bài viết trong chuỗi lập trình Python cơ bản có nhiều hàm được tích hợp sẵn của python được sử dụng như print(), len(), type(),... Trong phần này, chúng ta sẽ tập trung vào cách làm thế nào để tạo ra một function (hay còn gọi là Hàm). Trước khi bắt đầu tạo một hàm, chúng ta hãy tìm hiểu xem hàm là gì? tại sao chúng ta cần phải sử dụng nó?

Hàm là gì?

Function (hay còn gọi là Hàm): là một tập hợp các khối lệnh hoặc câu lệnh được viết ra để thực hiện một công việc nào đó nhằm phục vụ cho việc tái sử dụng lại sau này. Để định nghĩa một hàm, Python cung cấp từ khóa cho chúng ta từ khóa def. Sau đây là cú pháp để xác định một hàm. Nó sẽ được thực thi khi chúng ta gọi lại nó.

Khai báo và gọi một hàm

Khi chúng ta tạo một hàm, chúng ta gọi đó là khai báo một hàm. Khi bắt đầu sử dụng nó, ta gọi nó là gọi một hàm. Hàm có thể được khai báo có hoặc không có tham số.

# Khai báo một hàm
def function_name():
    codes

# Gọi lại hàm
function_name()

Không có tham số

Hàm có thể được khai báo mà không có tham số (tức bạn không sử dụng tham số).

def generate_full_name ():
    first_name = 'Chanh'
    last_name = 'Phan Nhat'
    space = ' '
    full_name = first_name + space + last_name
    print(full_name)
generate_full_name () # gọi một hàm

def add_two_numbers ():
    num_one = 2
    num_two = 3
    total = num_one + num_two
    print(total)
add_two_numbers() # gọi một hàm

Hàm trả về giá trị - Phần 1

Hàm cũng có thể trả về giá trị, nếu một hàm không trả về giá trị nào thì giá trị của hàm là Không. Thay vì sử dụng print() để in nó ra. Từ bây giờ, chúng ta sẽ sử dụng return để nhận một giá trị của kết quả trả về khi gọi hàm.

def generate_full_name ():
    first_name = 'Chanh'
    last_name = 'Phan Nhat'
    space = ' '
    full_name = first_name + space + last_name
    return full_name
print(generate_full_name()) # Chanh Phan Nhat

def add_two_numbers ():
    num_one = 2
    num_two = 3
    total = num_one + num_two
    return total
print(add_two_numbers()) # 5

Có tham số

Trong một hàm, chúng ta có thể chuyển các kiểu dữ liệu khác nhau (number, string, boolean, list, tuple, dictionary hoặc set) dưới dạng tham số

  • Hàm nhận một tham số: Nếu hàm của chúng ta nhận một tham số, chúng ta nên gọi hàm của mình bằng một đối số
# Khai báo một hàm
def function_name(parameter):
  codes

# gọi lại hàm
function_name(parameter)

Ví dụ:

def greetings (name):
    message = name + ', welcome to Python for Everyone!'
    return message
print(greetings('Chanh')) # Chanh, welcome to Python for Everyone!

def add_ten(num):
    ten = 10
    return num + ten
print(add_ten(90)) # 100

def square_number(x):
    return x * x
print(square_number(2)) # 4

def area_of_circle (r):
    PI = 3.14
    area = PI * r ** 2
    return area
print(area_of_circle(10)) # 314.0

def sum_of_numbers(n):
    total = 0
    for i in range(n+1):
        total+=i
    print(total)
sum_of_numbers(10) # 55
sum_of_numbers(100) # 5050
  • Hàm nhận hai tham số: Một hàm có thể có hoặc không có tham số hoặc các tham số. Một hàm có thể có hai hoặc nhiều tham số. Nếu hàm của chúng ta nhận tham số, chúng ta nên gọi nó là các đối số. Ví dụ về một hàm với hai tham số:
# khai báo một hàm
def function_name(para1, para2):
  codes

# gọi lại hàm
function_name(arg1, arg2)

Ví dụ:

def generate_full_name (first_name, last_name):
    space = ' '
    full_name = first_name + space + last_name
    return full_name
print('Full Name:', generate_full_name('Chanh','Phan Nhat')) # Full Name: Chanh Phan Nhat

def sum_two_numbers (num_one, num_two):
    sum = num_one + num_two
    return sum
print('Sum of two numbers:', sum_two_numbers(1, 9)) # Sum of two numbers: 10

def calculate_age (current_year, birth_year):
    age = current_year - birth_year
    return age;
print('Age:', calculate_age(2019, 1819)) # Age: 200

def weight_of_object (mass, gravity):
    weight = str(mass * gravity)+ ' N' # trước tiên giá trị phải được chuyển đổi thành chuỗi
    return weight
print ('Weight of an object in Newtons:', weight_of_object(100, 9.81)) # Weight of an object in Newtons: 981.0 N

Đối số với Key và Value

Nếu chúng ta truyền các đối số có Key và Value, thứ tự của các đối số không quan trọng. Để hiểu rõ hơn hãy xem các ví dụ sau

# khai báo một hàm
def function_name(para1, para2):
    codes

# gọi lại hàm
function_name(para1='Chanh', para2='Phan')

Ví dụ:

def print_fullname(firstname, lastname):
    space = ' '
    full_name = firstname  + space + lastname
    print(full_name)
print_fullname(firstname='Chanh', lastname='Phan') # Chanh Phan

def add_two_numbers (num1, num2):
    total = num1 + num2
    print(total)
add_two_numbers(num2=3, num1=2) # Thứ tự không thành vấn đề; KQ: 5

Hàm trả về giá trị - Phần 2

Nếu chúng ta không trả về giá trị với một hàm, thì hàm của chúng ta sẽ trả về Không theo mặc định. Để trả về một giá trị bằng một hàm, chúng ta sử dụng từ khóa return theo sau là biến mà chúng ta đang trả về. Chúng ta có thể trả về bất kỳ loại kiểu dữ liệu nào từ một hàm.

  • Trả về một string:
def print_name(firstname):
    return firstname
print_name('Chanh') # Chanh

def print_full_name(firstname, lastname):
    space = ' '
    full_name = firstname  + space + lastname
    return full_name
print_full_name(firstname='Chanh', lastname='Phan') # Chanh Phan
  • Trả lại một number:
def add_two_numbers (num1, num2):
    total = num1 + num2
    return total
print(add_two_numbers(2, 3)) # 5

def calculate_age (current_year, birth_year):
    age = current_year - birth_year
    return age;
print('Age:', calculate_age(2019, 1819)) # Age: 200
  • Trả lại kiểu boolean:
def is_even (n):
    if n % 2 == 0:
        print('even') # even
        return True   # return dừng thực hiện thêm chức năng, tương tự như break
    return False
print(is_even(10)) # True
print(is_even(7))  # False
  • Trả về một list:
def find_even_numbers(n):
    evens = []
    for i in range(n+1):
        if i % 2 == 0:
            evens.append(i)
    return evens
print(find_even_numbers(10)) # [0, 2, 4, 6, 8, 10]

Hàm với các tham số mặc định

Đôi khi chúng ta chuyển các giá trị mặc định cho các tham số, khi chúng ta gọi hàm. Nếu chúng ta không truyền các đối số khi gọi hàm, các giá trị mặc định của chúng sẽ được sử dụng.

# Khai báo một hàm
def function_name(param = value):
    codes
    codes

# gọi lại hàm
function_name()
function_name(arg)

Ví dụ:

def greetings (name = 'Peter'):
    message = name + ', welcome to Python for Everyone!'
    return message
print(greetings())        # Peter, welcome to Python for Everyone!
print(greetings('Chanh')) # Chanh, welcome to Python for Everyone!

def generate_full_name (first_name = 'Chanh', last_name = 'Phan'):
    space = ' '
    full_name = first_name + space + last_name
    return full_name

print(generate_full_name()) # Chanh Phan
print(generate_full_name('David','Smith')) # David Smith

def calculate_age (birth_year,current_year = 2019):
    age = current_year - birth_year
    return age;
print('Age:', calculate_age(1819)) # Age: 200

def weight_of_object (mass, gravity = 9.81):
    weight = str(mass * gravity)+ ' N' # the value has to be changed to string first
    return weight
print('Weight of an object in Newtons:', weight_of_object(100))       # Weight of an object in Newtons: 981.0 N
print('Weight of an object in Newtons:', weight_of_object(100, 1.62)) # Weight of an object in Newtons: 162.0 N

Số lượng đối số tùy ý

Nếu chúng ta không biết số lượng đối số mà chúng ta cần truyền vào hàm của mình, chúng ta có thể tạo một hàm có thể nhận số lượng đối số tùy ý bằng cách thêm dấu * vào trước tên tham số.

# Khai báo một hàm
def function_name(*args):
    codes
    codes

# Gọi lại hàm
function_name(param1, param2, param3,..)

Ví dụ:

def sum_all_nums(*nums):
    total = 0
    for num in nums:
        total += num  # giống như total = total + num
    return total
print(sum_all_nums(2, 3, 5)) # 10

Số lượng tham số mặc định và tùy ý trong hàm

def generate_groups (team,*args):
    print(team)
    for i in args:
        print(i)
generate_groups('Team-1','Alex','Brook','David','Eyob')

# Team-1
# Alex
# Brook
# David
# Eyob

Hàm như một tham số của một hàm khác

Bạn có thể sử dụng hàm thứ nhất làm tham số cho các hàm khác (tham số là một hàm)

def square_number (n):
    return n * n
def do_something(f, x):
    return f(x)
print(do_something(square_number, 3)) # 9

Hàm vô danh (Lambda function)

  • Trong Python, hiểu đơn giản hàm vô danh là hàm được định nghĩa mà không có tên hàm. Cú pháp lambda <tham_số>: <biểu_thức>

    square = lambda x: x ** 2
    x = [1, 2, 3, 4]
    y = map(square, x)
    print(list(y)) #KQ: [1, 4, 9, 16]
  • Thật tiện lợi nhưng đừng sử dụng thường xuyên, hãy sử dụng def để thay thế.

    x = lambda a : a + 10
    print(x(5)) #KQ: 15
    
    # Bạn  thể sử dụng def
    def x(a): return a + 10
    print(x(5)) #KQ: 15
  • if else với hàm lambda

    lambda row: 'good' if (row>=80) else ('bad' if row<80 else '')

Xử lý ngoại lệ (Exception Handling)

Ngoại lệ (Exception) là lỗi xảy ra trong quá trình thực thi một chương trình. Khi nó xảy ra, Python tạo ra một exception để xử lý vấn đề đó tránh cho ứng dụng hay server của bạn bị crash. Có thể được xử lý bằng bằng các cấu trúc sau:

try:
  # codes
except:
  # codes chạy nếu  một ngoại lệ
try:
  # codes
except:
  # codes chạy nếu  một ngoại lệ
else:
  # không  ngoại lệ
try:
  # try codes
except FileNotFoundError as fnf_error:
    print(fnf_error)
except AssertionError as error:
    print(error)
  • Ví dụ 1

    if par1 is None:
    msg = "par1 phải ở kiểu `int`"
    raise TypeError(msg)
  • Ví dụ 2

    d = 0
    
    # Phép chia này  vấn đề, cho cho 0
    # Một lỗi được phát ra tại đây.
    value = 10 / d
    
    # Dòng  dưới đây sẽ không được thực thi.
    print ("Let's go!")

    Sửa lại một tí ta được:

    d = 0
    
    try :
        # Phép chia này  vấn đề, chia cho 0.
        # Một lỗi được phát ra tại đây (ZeroDivisionError).
        value = 10 / d
    
        print ("Value = ", value)
    
    except ZeroDivisionError as e :
    
        print ("Error: ", str(e) )
        print ("Ignore to continue ...")
    
    print ("Let's go!")
  • Ví dụ 3: Xây dựng một Exception

    try:
        x = input('Nhập một số trong khoảng 1-10: ')
        if x<1 or x>10:
        raise Exception
        print 'Bạn vừa nhập một số hợp lệ :D'
    
    except:
        print 'Số bạn vừa nhập nằm ngoài khoảng cho phép mất rồi!'
  • Ví dụ 4

    element = 'mean'
    try:
        print(float(element)) #element  kiểu str không phải float nên xuất hiện exception
    except ValueError:
        if element == 'mean':
            print('hello mean')
  • Bạn có thể kiểm tra các trường họp ngoại lệ khác tại đây

Như vậy, chúng ta đã tìm hiểu xong cách tạo một hàm cũng như sử dụng một hàm trong ngôn ngữ python là như thế nào rồi. Tiếp theo, hãy làm một số bài tập để cũng cố lại nội dung đã tìm hiểu.

Bài tập

  1. Khai báo một hàm add_two_numbers. Nó nhận hai tham số và trả về một tổng sum.
  2. Viết một hàm tính toán diện tích hình tròn. area=πarea = π x r2r^2
  3. Viết một hàm có tên add_all_nums nhận số lượng đối số tùy ý và tính tổng tất cả các đối số. Kiểm tra xem tất cả các đối số trong list có phải là kiểu numbers không. Nếu không đưa ra một thông báo hợp lý.
  4. Nhiệt độ tính bằng °C có thể được chuyển đổi thành °F bằng công thức này: °F = (°C x 9/5) + 32. Viết hàm chuyển đổi °C thành °F, convert_celcius_to_fahrenheit.
  5. Viết một hàm có tên là check_season, nó nhận tham số là month và trả về season: Autumn, Winter, Spring hoặc Summer.
  6. Viết một hàm có tên là calcul_slope trả về hệ số góc của một phương trình tuyến tính.
  7. Phương trình bậc hai được tính như sau: ax² + bx + c = 0. Viết một hàm tính tập nghiệm của một phương trình bậc hai, solve_quadratic_eqn.
  8. Khai báo một hàm có tên print_list. Nó lấy một list làm các tham số và in ra từng phần tử của list đó.
  9. Khai báo một hàm có tên là reverse_list. Nhận một mảng làm tham số và nó trả về phần ngược lại của mảng (sử dụng vòng lặp).
print(reverse_list([1, 2, 3, 4, 5]))  # [5, 4, 3, 2, 1]
print(reverse_list1(["A", "B", "C"])) # ["C", "B", "A"]
  1. Khai báo một hàm có tên là capitalize_list_items. Nó nhận một list làm tham số và nó trả về một list gồm các item được viết hoa.
  2. Khai báo một hàm có tên add_item. Nó có một list gồm các item. Kết quả trả về một list với các item mới được thêm vào cuối list.
food_staff = ['Potato', 'Tomato', 'Mango', 'Milk'];
print(  add_item(food_staff, 'Meat'))  # ['Potato', 'Tomato', 'Mango', 'Milk','Meat'];
numbers = [2, 3, 7, 9];
print(add_item(numbers, 5))            # [2, 3, 7, 9, 5]
  1. Khai báo một hàm có tên remove_item. Nó có một list gồm các item. Kết quả trả về một list mới khi xóa các item được chỉ định có trong list đó.
food_staff = ['Potato', 'Tomato', 'Mango', 'Milk'];
print(remove_item(food_staff, 'Mango'))  # ['Potato', 'Tomato', 'Milk'];
numbers = [2, 3, 7, 9];
print(remove_item(numbers, 3))  # [2, 7, 9]
  1. Khai báo một hàm có tên sum_of_numbers. Nhận một tham số và tính tổng tất cả các số trong phạm vi đó.
print(sum_of_numbers(5))  # 15
print(sum_all_numbers(10)) # 55
print(sum_all_numbers(100)) # 5050
  1. Khai báo một hàm có tên sum_of_odds. Nhận một tham số số và tính tổng tất cả các số chẵn và số lẻ trong phạm vi đó.
  2. Viết mọt hàm để tính giai thừa của một số nguyên.
  3. Viết một hàm có tên is_empty, nhận một tham số và nó sẽ kiểm tra xem nó có rỗng hay không
  4. Viết hàm is_prime, hàm này kiểm tra xem một số có phải là số nguyên tố không.
  5. Viết một hàm kiểm tra xem tất cả các item có phải là duy nhất trong một list hay không.
  6. Viết một hàm để kiểm tra xem tất cả các item trong list có cùng kiểu dữ liệu hay không.
  7. Viết một hàm để kiểm tra xem biến được khai báo có phải là một biến hợp lệ hay không.
  8. Tải file có tên countries-data.py
    • Tạo một hàm có tên là most_spoken_languages. Trả về 10 hoặc 20 ngôn ngữ phổ biến nhất trên thế giới theo thứ tự giảm dần.
    • Tạo một hàm có tên là most_populated_countries. Trả về 10 hoặc 20 quốc gia đông dân nhất thế giới theo thứ tự giảm dần.