1.Các hàm bên trong một class, luôn có tham số self, self là bắt buộc của cú pháp hay chỉ là tên mà người ta quy ước với nhau
self
là đại diện cho instance
. Hãy xem ví dụ sau đây
class A:
def wazzup(): # method không có parameter self
print("Wazzupppp!")
Mình sẽ cho bạn thấy sự khác biệt giữa có self
và không có self
>>> A.wazzup() # kết quả dễ đoán
Wazzupppp!
>>> ob = A() # tạo một đối tượng, đối tượng này là instance của lớp A
>>> ob.wazzup()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: wazzup() takes 0 positional arguments but 1 was given
Bạn thấy chứ, wazzup() takes 0 positional arguments but 1 was given
. Rõ ràng ta không truyền bất cứ argument
nào nhưng nó lại báo là đã truyền 1. Sự thật là mình đã truyền một argument
là đối tượng ob
. Và đương nhiên chúng ta cần một parameter
trong phương thức để nhận lấy giá trị đó. Và người ta quy ước dùng self
. Vì sao là quy ước? Bởi vì nó chỉ là parameter
thôi, bạn hoàn toàn có thể thay thế những chữ cái khác nếu bạn thích. Theo mình biết là như thế, tại mình từng vọc và thay thế self
bằng chữ trời ơi đất hỡi khác và vẫn được.
2.Class abc(object): kế thừa lớp object, vậy cái class object nó ở chỗ nào và nó có những phương thức nào ạ
Thật ra thì text editor
nó in ra thế thôi chứ làm gì có object
nào . Nó giống như việc nó gõ dùm bạn syntax sẵn thôi.
3.Anh có thể giả thích kĩ hơn cách mà hàm__init__ hoạt động giúp em được không ạ.
Cái phương thức này đặc biệt ở chỗ nó sẽ tự động được invoke
(gọi) khi khởi tạo đối tượng. Cũng còn một cái method nữa cũng sẽ được invoke
nhưng cũng chả nhớ lắm vì nó không quan trọng. Nó giống như là một cái setup dùm attribute cho đói tượng dùm mình. Lấy ví dụ đơn giản không dùng __init__
class A:
pass # không có ý nghĩa gì đâu
>>> ob = A() # ob là một đối tượng của lớp A
>>> ob.name = "object" # khởi tạo một attribute tên name, giá trị "object"
>>> ob.age = 16 # khởi tạo một attribute tên age, giá trị 16
>>> ob.level = 200 # khởi tạo một attribute tên level, giá trị 200
>>> ob.name # và nó cũng giống như biến
"object"
>>> ob.age, ob.level
(16, 200)
Đặt vấn đề, bạn phải khai báo 100 đối tượng (không dùng loop - vòng lặp) thì bạn phải mất 1 dòng khởi tạo đối tương, 3 dòng khởi tạo các attribute tổng cộng là 4 dòng 1 đối tượng => 400 dòng 100 đối tượng. Ta hãy than khảo phương thức __init__
nhé
class A:
def __init__(self, p_name, p_age, p_level):
self.name = p_name
self.age = p_age
self.level = p_level
Ta sẻ khởi tạo đối tượng, nhớ là thêm cho đủ 4 argument
>>> ob = A("object", 16, 200) # self là ob, "object" là p_name, 16 là p_age còn 200 là p_level
Và hãy thay thế những thứ mới đề cập đi nào
def __init__(self, p_name, p_age, p_level):
self.name = p_name
self.age = p_age
self.level = p_level
Sẽ được biến hóa thành
def __init__(ob, "object", 16, 200):
ob.name = "object"
ob.age = 16
ob.level = 200
Vậy ta chỉ cần 100 dòng cho 100 đối tượng. + 4 dòng cho phương thức __init__
là 104
Không những thế, bạn còn tránh sai sót khi khởi tạo thiếu attribute mà bạn không hề biết.