Bài viết Câu hỏi About RongvangIT
profile Pic
1
1

Đăng ngày:

 

Sửa ngày:

111 Lượt xem

Sử dụng hiệu quả Python: Giải thích đầy đủ cho tất cả 71 hàm tích hợp sẵn [P2]

Python

Python là một trong những ngôn ngữ lập trình phổ biến trên toàn thế giới. Một trong những đặc điểm nổi bật của Python là việc nó có một loạt các hàm tích hợp sẵn phong phú.

Tính đến tháng 12 năm 2023, Python có tổng cộng 71 hàm tích hợp sẵn. Tuy nhiên, có bao nhiêu người thực sự biết cách sử dụng chúng hiệu quả?

Trong bài viết này, chúng ta sẽ cung cấp một giải thích chi tiết về cách sử dụng tất cả 71 hàm tích hợp sẵn trong Python, kèm theo ví dụ mã nguồn thực tế. Sau khi đọc bài viết này, bạn sẽ có hiểu biết toàn diện về các hàm tích hợp sẵn của Python từ cơ bản đến nâng cao.

Bắt đầu thôi nào!

Danh sách tất cả hàm tích hợp sẵn

(11) bytes()

Trả về một đối tượng dãy không thay đổi biểu diễn một chuỗi byte được chỉ định bởi đối số.

# Nếu đối số là số nguyên, tạo một chuỗi byte với độ dài là số đó, được điền bằng các byte có giá trị 0.
b = bytes(5)
print(b) # b'\x00\x00\x00\x00\x00'

# Nếu đối số là một chuỗi, chuyển đổi nó thành một chuỗi byte sử dụng một bảng mã chỉ định.
b = bytes("Hello", "utf-8")
print(b) # b'Hello'

# Nếu đối số là một đối tượng có thể lặp, sử dụng các phần tử của nó như giá trị byte.
b = bytes([65, 66, 67])
print(b) # b'ABC'
  • Lưu ý
    Vì đối tượng bytes là không thay đổi, nó không thể thay đổi, thêm hoặc xóa phần tử. Do đó, để tạo một chuỗi byte mới, bạn cần nối nó với một đối tượng bytes khác hoặc chuyển đổi nó thành đối tượng bytearray.
b = b"Hello"
b[0] = 74  # bytes là không thay đổi nên sẽ báo lỗi
# TypeError: 'bytes' object does not support item assignment

b += b"!"  # Tạo một đối tượng bytes mới và nối vào đối tượng cũ
print(b)  # b'Hello!'

ba = bytearray(b)  # Chuyển đổi thành đối tượng bytearray
ba[0] = 74  # bytearray là thay đổi nên có thể thay đổi giá trị
print(ba)  # bytearray(b'Jello!')

:::note warn
Nếu không biết về hàm này…
Khi làm việc với chuỗi byte, người ta thường sử dụng chuỗi thay vì bytes. Chuỗi phụ thuộc vào mã hóa, nên không thể xử lý dữ liệu nhị phân. Do đó, có thể gặp vấn đề khi đọc/ghi tệp hoặc giao tiếp qua mạng.

s = "Hello"
f = open("test.txt", "w")  # Mở tệp ở chế độ văn bản
f.write(s)  # Ghi chuỗi vào tệp
f.close()

f = open("test.txt", "rb")  # Mở tệp ở chế độ nhị phân
b = f.read()  # Đọc chuỗi byte
f.close()
print(b)  # b'Hello'

s = "こんにちは"
f = open("test.txt", "w")  # Mở tệp ở chế độ văn bản
f.write(s)  # Ghi chuỗi vào tệp
f.close()

f = open("test.txt", "rb")  # Mở tệp ở chế độ nhị phân
b = f.read()  # Đọc chuỗi byte
f.close()
print(b)  # b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'

Bằng cách sử dụng hàm bytes, bạn có thể dễ dàng chuyển đổi chuỗi thành chuỗi byte.

s = "Hello"
b = bytes(s, "utf-8")  # Chuyển đổi chuỗi thành chuỗi byte
f = open("test.txt", "wb")  # Mở tệp ở chế độ nhị phân
f.write(b)  # Ghi chuỗi byte vào tệp
f.close()

f = open("test.txt", "rb")  # Mở tệp ở chế độ nhị phân
b = f.read()  # Đọc chuỗi byte
f.close()
print(b)  # b'Hello'

s = "こんにちは"
b = bytes(s, "utf-8")  # Chuyển đổi chuỗi thành chuỗi byte
f = open("test.txt", "wb")  # Mở tệp ở chế độ nhị phân
f.write(b)  # Ghi chuỗi byte vào tệp
f.close()

f = open("test.txt", "rb")  # Mở tệp ở chế độ nhị phân
b = f.read()  # Đọc chuỗi byte
f.close()
print(b)  # b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'

:::

(12) callable()

Trả về True nếu đối số là một đối tượng có thể gọi được (ví dụ: hàm hoặc phương thức), ngược lại trả về False.

def add(x, y):
    return x + y

print(callable(add))  # True
print(callable(3))  # False
print(callable(print))  # True
print(callable("Hello"))  # False
  • Lưu ý
    callable chỉ kiểm tra xem đối tượng có thể gọi được hay không, không thực sự thực hiện việc gọi. Để thực hiện việc gọi, bạn cần sử dụng cú pháp gọi hàm với dấu ngoặc và các đối số tương ứng.
def add(x, y):
    return x + y

callable(add)  # True
add(3, 4)  # 7

callable(3)  # False
3(5)  # Lỗi sẽ xảy ra
# TypeError: 'int' object is not callable

:::note warn
Nếu không biết về hàm này…
Khi kiểm tra xem một đối tượng có thể gọi được hay không, một số người có thể s

ử dụng câu lệnh try-except để bắt lỗi. Tuy nhiên, điều này làm cho mã nguồn trở nên rườm rà và có thể ảnh hưởng đến hiệu suất.

def add(x, y):
    return x + y

def is_callable(obj):
    try:
        obj()
        return True
    except TypeError:
        return False

print(is_callable(add))  # True
print(is_callable(3))  # False

Sử dụng hàm callable giúp viết mã ngắn gọn hơn.

def add(x, y):
    return x + y

print(callable(add))  # True
print(callable(3))  # False

:::

(13) chr()

Trả về ký tự mà Unicode code point được chỉ định bởi đối số biểu diễn.

print(chr(65))  # A
print(chr(97))  # a
print(chr(12354))  # あ
print(chr(128512))  #
  • Lưu ý
    Đối số phải là số nguyên trong khoảng từ 0 đến 1114111. Các giá trị khác sẽ gây ra lỗi.
print(chr(-1))  # Lỗi
# ValueError: chr() arg not in range(0x110000)

print(chr(1114112))  # Lỗi
# ValueError: chr() arg not in range(0x110000)

:::note warn
Nếu không biết về hàm này…
Để có được ký tự từ Unicode code point, một số người sẽ sử dụng mã hóa hoặc chuỗi byte để chuyển đổi. Điều này phức tạp và dễ gây lỗi.

# Sử dụng mã hóa UTF-8 để có được ký tự từ code point
def codepoint_to_char(codepoint):
    b = codepoint.to_bytes(4, "big")  # Chuyển code point thành chuỗi byte
    b = b.lstrip(b"\x00")  # Loại bỏ các byte 0 ở đầu
    return b.decode("utf-8")  # Chuyển đổi chuỗi byte thành chuỗi

print(codepoint_to_char(65))  # A
print(codepoint_to_char(97))  # a
print(codepoint_to_char(12354))  # あ
print(codepoint_to_char(128512))  #

Sử dụng hàm chr giúp đơn giản hóa việc lấy ký tự.

print(chr(65))  # A
print(chr(97))  # a
print(chr(12354))  # あ
print(chr(128512))  #

:::

(14) classmethod()

Chuyển đổi một phương thức của lớp thành một phương thức của lớp. Phương thức của lớp có thể được gọi trực tiếp từ lớp mà không cần tạo một đối tượng của lớp.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def from_birth_year(cls, name, birth_year):
        age = 2023 - birth_year
        return cls(name, age)

p1 = Person("Alice", 25)
p2 = Person.from_birth_year("Bob", 1998)
print(p1.name, p1.age)  # Alice 25
print(p2.name, p2.age)  # Bob 25

:::note info
Khi cần thiết
Phương thức của lớp thường được sử dụng để tạo các đối tượng của lớp một cách linh hoạt hơn.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def from_birth_year(cls, name, birth_year):
        age = 2023 - birth_year
        return cls(name, age)

p1 = Person("Alice", 25)
p2 = Person.from_birth_year("Bob", 1998)
print(p1.name, p1.age)  # Alice 25
print(p2.name, p2.age)  # Bob 25

Với classmethod, bạn có thể tạo đối tượng của lớp dựa trên đối số theo cách linh hoạt.

class Student(Person):
    def __init__(self, name, age, school):
        super().__init__(name, age)
        self.school = school

    @classmethod
    def from_birth_year(cls, name, birth_year, school):
        age = 2023 - birth_year
        return cls(name, age, school)

s1 = Student("Charlie", 18, "Tokyo University")
s2 = Student.from_birth_year("David", 2005, "Tokyo High School")
print(s1.name, s1.age, s1.school)  # Charlie 18 Tokyo University
print(s2.name, s2.age, s2.school)  # David 18 Tokyo High School

Với classmethod, bạn có thể tạo đối tượng của lớp dựa trên đối số theo cách linh hoạt, và phương thức của lớp cũng có thể được sử dụng trong các lớp con.
:::

(15) compile()

Hàm compile() chuyển đổi mã nguồn được chỉ định (dưới dạng chuỗi hoặc dãy byte) thành một đối tượng mã nguồn có thể được thực thi bởi trình biên dịch Python. Đối tượng mã nguồn này có thể được sử dụng để đánh giá mã nguồn động hoặc lưu trữ nó trong một tệp.

# Chỉ định mã nguồn, tên tệp, và chế độ (exec, eval, single)
code = compile("x = 3\ny = 4\nprint(x + y)", "<string>", "exec")  # Biên dịch chuỗi thành đối tượng mã nguồn
exec(code)  # Thực thi đối tượng mã nguồn
# 7

code = compile("x * y", "<string>", "eval")  # Biên dịch biểu thức thành đối tượng mã nguồn
x = 3
y = 4
result = eval(code)  # Đánh giá đối tượng mã nguồn
print(result)  # 12

code = compile("x + y\n", "<string>", "single")  # Biên dịch biểu thức tương tác thành đối tượng mã nguồn
x = 3
y = 4
exec(code)  # Thực thi đối tượng mã nguồn
# 7
  • Lưu ý:
    • Hàm compile() chỉ chuyển đổi mã nguồn thành đối tượng mã nguồn mà không thực sự thực thi nó. Để thực thi, bạn có thể sử dụng exec() hoặc eval() với đối tượng mã nguồn tương ứng.
    • Sử dụng exec() để thực thi mã nguồn có chứa các câu lệnh.
    • Sử dụng eval() để đánh giá một biểu thức và nhận giá trị kết quả.
code = compile("print('Hello')", "<string>", "exec")  # Biên dịch câu lệnh thành đối tượng mã nguồn
exec(code)  # Thực thi đối tượng mã nguồn
# Hello

:::note warn
Nếu không biết về hàm này…
Khi thực hiện đánh giá mã nguồn động hoặc lưu trữ mã nguồn trong một tệp, việc sử dụng exec() hoặc eval() trực tiếp có thể mang lại rủi ro về bảo mật và có thể ảnh hưởng đến hiệu suất.

# Sử dụng exec() để thực thi mã nguồn trực tiếp
exec("x = 3\ny = 4\nprint(x + y)")  # 7

# Sử dụng eval() để đánh giá biểu thức trực tiếp
x = 3
y = 4
result = eval("x * y")  # 12

Bằng cách sử dụng hàm compile(), bạn có thể chuyển đổi mã nguồn thành đối tượng mã nguồn trước, giúp tăng tính linh hoạt và an toàn trong việc thực thi mã nguồn động.

code = compile("x = 3\ny = 4\nprint(x + y)", "<string>", "exec")  # Biên dịch thành đối tượng mã nguồn
exec(code)  # Thực thi đối tượng mã nguồn
# 7

:::

(16) complex()

Hàm complex() tạo ra một số phức từ các thành phần số thực và số ảo được chỉ định. Số phức là tổ hợp của số thực và số ảo, thường được biểu diễn dưới dạng a + bi.

# Chỉ định số thực và số ảo
c = complex(2, 3)  # 2 + 3i
print(c)  # (2+3j)
print(c.real)  # 2.0
print(c.imag)  # 3.0

# Nếu chỉ có một đối số, nó được coi là số thực, số ảo sẽ là 0
c = complex(5)  # 5 + 0i
print(c)  # (5+0j)

# Chỉ định dưới dạng chuỗi cũng được chấp nhận
c = complex("2+3j")  # 2 + 3i
print(c)  # (2+3j)
  • Lưu ý:
    • Đối số phải là số hoặc chuỗi. Bất kỳ loại dữ liệu khác đều sẽ gây ra lỗi.
c = complex([1, 2])  # Lỗi
# TypeError: complex() first argument must be a string or a number, not 'list'
  • Khi sử dụng chuỗi, cần đảm bảo chuỗi biểu diễn một số phức theo đúng định dạng. Sự xuất hiện của khoảng trắng hoặc các ký tự không mong muốn có thể dẫn đến lỗi.
c = complex("2 + 3j")  # Lỗi
# ValueError: complex() arg is a malformed string

c = complex("2+3i")  # Lỗi
# ValueError: complex() arg is a malformed string

:::note warn
Nếu không biết về hàm này…
Khi làm việc với số phức, một số người thường tự quản lý các phần riêng lẻ của số phức (số thực và số ảo). Điều này có thể làm

cho mã nguồn phức tạp và dễ xảy ra lỗi.

# Quản lý số thực và số ảo riêng lẻ
real = 2
imag = 3
print(f"{real} + {imag}i")  # 2 + 3i

# Khi thực hiện phép toán trên số phức, cần phải tính riêng từng phần
real2 = 4
imag2 = 5
# (2 + 3i) + (4 + 5i) = (6 + 8i)
real_sum = real + real2
imag_sum = imag + imag2
print(f"{real_sum} + {imag_sum}i")  # 6 + 8i

Bằng cách sử dụng hàm complex(), bạn có thể quản lý số phức một cách thuận tiện, đơn giản hóa mã nguồn và giảm khả năng xảy ra lỗi.

# Quản lý số phức bằng một đối tượng
c1 = complex(2, 3)  # 2 + 3i
print(c1)  # (2+3j)

# Thực hiện phép toán trên đối tượng số phức
c2 = complex(4, 5)  # 4 + 5i
# (2 + 3i) + (4 + 5i) = (6 + 8i)
c_sum = c1 + c2
print(c_sum)  # (6+8j)

:::

(17) delattr()

Hàm delattr() xóa một thuộc tính từ một đối tượng dựa trên tên thuộc tính được chỉ định. Thuộc tính là các biến hoặc phương thức liên kết với đối tượng.

class Person:
    def __init__(self, name, age):
        self.name = name  # Thuộc tính
        self.age = age  # Thuộc tính

    def greet(self):  # Phương thức
        print(f"Hello, I'm {self.name}.")

p = Person("Alice", 25)  # Tạo đối tượng
p.greet()  # Hello, I'm Alice.
print(p.age)  # 25

delattr(p, "age")  # Xóa thuộc tính khỏi đối tượng
print(p.age)  # Thuộc tính đã bị xóa nên sẽ có lỗi
# AttributeError: 'Person' object has no attribute 'age'
  • Lưu ý:
    • Đối số đầu tiên của delattr() là đối tượng cần xóa thuộc tính từ, và đối số thứ hai là tên thuộc tính cần xóa.
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person("Alice", 25)
delattr(p, p.age)  # Lỗi, cần truyền vào tên thuộc tính chứ không phải giá trị thuộc tính
# TypeError: attribute name must be string

:::note info
Khi cần thiết…
Hàm delattr() tập trung vào việc xóa một thuộc tính cụ thể từ một đối tượng, giúp làm rõ ý định của mã nguồn. So với câu lệnh del, delattr() chỉ xóa thuộc tính và không ảnh hưởng đến các biến khác.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person("Alice", 25)
del p.age  # Sử dụng câu lệnh del để xóa thuộc tính
print(p.age)  # Thuộc tính đã bị xóa nên sẽ có lỗi
# AttributeError: 'Person' object has no attribute 'age'
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person("Alice", 25)
delattr(p, "age")  # Sử dụng delattr() để xóa thuộc tính
print(p.age)  # Thuộc tính đã bị xóa nên sẽ có lỗi
# AttributeError: 'Person' object has no attribute 'age'

Sử dụng delattr() giúp làm cho mã nguồn trở nên rõ ràng hơn với việc xóa thuộc tính cụ thể từ đối tượng.
:::

(18) dict()

Hàm dict() tạo và trả về một từ điển từ các cặp khóa và giá trị được chỉ định dưới dạng đối số.

# Chỉ định cặp khóa và giá trị bằng cách sử dụng đối số từ khóa
d = dict(name="Alice", age=25)
print(d)  # {'name': 'Alice', 'age': 25}

# Chỉ định cặp khóa và giá trị bằng cách sử dụng đối số từ một đối tượng có thể lặp
d = dict([("name", "Alice"), ("age", 25)])
print(d)  # {'name': 'Alice', 'age': 25}

# Chỉ định cặp khóa và giá trị từ một từ điển hiện có
d = dict({"name": "Alice", "age": 25})
print(d)  # {'name': 'Alice', 'age': 25}
  • Lưu ý:
    • Đối số phải là cặp khóa và giá trị. Nếu không có cặp khóa và giá trị, hoặc nếu có cặp khóa trùng lặp, sẽ xảy ra lỗi.
d = dict(3)  # Lỗi, không có cặp khóa và giá trị
# TypeError: cannot convert dictionary update sequence element #0 to a sequence

d = dict(name="Alice", name="Bob")  # Lỗi, cặp khóa trùng lặp
# TypeError: dict() got multiple values for keyword argument 'name'

:::note warn
Nếu không biết về hàm này…
Khi bạn cần tạo một từ điển từ các cặp khóa và giá trị được chỉ định, thay vì sử dụng cú pháp từ điển literal ({}), bạn có thể sử dụng hàm dict() để làm cho mã nguồn của mình trở nên linh hoạt và dễ đọc hơn.

# Sử dụng cú pháp từ điển literal
d = {"name": "Alice", "age": 25}
print(d)  # {'name': 'Alice', 'age': 25}

# Sử dụng hàm dict() để tạo từ điển
d = dict(name="Alice", age=25)
print(d)  # {'name': 'Alice', 'age': 25}

Hàm dict() có thể giúp làm cho mã nguồn trở nên rõ ràng hơn, đặc biệt là khi bạn có các cặp khóa và giá trị được tạo ra động.

# Tạo từ điển từ các cặp khóa và giá trị được tạo động
keys = ["name", "age"]
values = ["Alice", 25]
d = dict(zip(keys, values))
print(d)  # {'name': 'Alice', 'age': 25}

:::

(19) dir()

Hàm dir() trả về một danh sách các tên thuộc tính và phương thức của một đối tượng. Nếu không có đối tượng nào được chỉ định, nó sẽ trả về danh sách các tên trong phạm vi cục bộ hiện tại.

class Sample:
    def __init__(self, name):
        self.name = name

    def hello(self):
        print(f"Hello, {self.name}!")

sample = Sample("Bing")
print(dir(sample))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hello', 'name']

print(dir())
# ['Sample', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'sample']
  • Lưu ý:
    • Nếu không có đối tượng nào được chỉ định, dir() sẽ trả về danh sách các tên trong phạm vi cục bộ hiện tại.

:::note info
Khi cần thiết…
Hàm dir() là một công cụ mạnh mẽ khi bạn muốn khám phá các thuộc tính và phương thức của một đối tượng Python. Nó có thể giúp bạn hiểu rõ hơn về cấu trúc và khả năng của đối tượng đó.

# Sử dụng dir() để khám phá các thuộc tính và phương thức của đối tượng
dir_result = dir(sample)
print(dir_result)
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hello', 'name']

# Sử dụng dir() để khám phá các tên trong phạm vi cục bộ hiện tại
local_scope_names = dir()
print(local_scope_names)
# ['Sample', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'sample']

Khi bạn gặp một đối tượng mới hoặc không quen thuộc, dir() là một công cụ hữu ích để tìm hiểu về cấu trúc và khả năng của nó.
:::

(20) divmod()

Hàm divmod() trả về một bộ giá trị chứa kết quả của phép chia lấy phần nguyên và phần dư của hai số được chia.

print(divmod(7, 3))
# (2, 1)



print(divmod(7.5, 3))
# (2.0, 1.5)
  • Lưu ý:
    • Kết quả trả về là một bộ giá trị, với phần tử đầu tiên là kết quả phép chia lấy phần nguyên và phần tử thứ hai là phần dư.

:::note warn
Nếu không biết về hàm này…
Khi bạn cần tính toán cả kết quả của phép chia lấy phần nguyên và phần dư của hai số, bạn có thể sử dụng divmod() để giảm bớt sự lặp lại và làm cho mã nguồn của mình trở nên ngắn gọn hơn.

# Sử dụng toán tử / và %
x = 7
y = 3
quotient = x // y
remainder = x % y
result = (quotient, remainder)
print(result)
# (2, 1)
# Sử dụng hàm divmod()
x = 7
y = 3
result = divmod(x, y)
print(result)
# (2, 1)

Hàm divmod() giúp làm cho mã nguồn trở nên rõ ràng hơn và thể hiện rõ ràng ý định của bạn khi bạn muốn tính cả phần nguyên và phần dư.
:::

Bình luận

Bài viết chưa có bình luận. Hãy trở thành người bình luận đầu tiên!
Sign up for free and join this conversation.
Sign Up
If you already have a RongvangIT account Login
Danh sách thư mục
Bắt đầu ngay với RồngVàngIT - nền tảng chia sẻ kiến thức lập trình tuyệt vời cho kỹ sư Việt Nam!

Hãy đăng nhập để sử dụng hàng loạt các chức năng tuyệt vời của RồngVàngIT !

  1. 1. Bạn sẽ nhận được các bài viết phù hợp bằng chức năng theo dõi tag và người dùng.
  2. 2. Bạn có thể đọc lại các thông tin hữu ích bằng chức năng lưu trữ nội dung.
  3. 3. Chia sẻ kiến thức, đặt câu hỏi và ghi lại quá trình trưởng thành của mình cùng RồngVàngIT !
Tạo tài khoản Đăng nhập
profile Pic