Giới thiệu về Python
Nắm vững kiến thức cơ bản về phân tích dữ liệu với Python chỉ trong bốn giờ. Khóa học trực tuyến này sẽ giới thiệu giao diện Python và khám phá các gói phổ biến
Python trung cấp
Nâng cao kỹ năng khoa học dữ liệu của bạn bằng cách tạo trực quan hóa bằng Matplotlib và thao tác với DataFrames bằng gấu trúcCó liên quan
Dữ liệu văn bản trong Python Cheat Sheet
Chào mừng bạn đến với bảng gian lận của chúng tôi để làm việc với dữ liệu văn bản trong Python. Chúng tôi đã biên soạn một danh sách các hàm và gói hữu ích nhất để dọn dẹp, xử lý và phân tích dữ liệu văn bản trong Python, cùng với các ví dụ và giải thích rõ ràng, vì vậy bạn sẽ có mọi thứ cần biết về cách làm việc với dữ liệu văn bản trong Python.Hướng dẫn về tập hợp và lý thuyết tập hợp trong Python
Tìm hiểu về bộ Python. chúng là gì, cách tạo chúng, khi nào sử dụng chúng, các chức năng tích hợp và mối quan hệ của chúng với các hoạt động lý thuyết thiết lậpHướng dẫn về gấu trúc. Khung dữ liệu trong Python
Khám phá phân tích dữ liệu với Python. Pandas DataFrames giúp thao tác dữ liệu của bạn dễ dàng, từ việc chọn hoặc thay thế các cột và chỉ mục để định hình lại dữ liệu của bạnXem ThêmXem ThêmMột số ngôn ngữ lập trình như Python, C++, v.v., cho phép các lớp kế thừa nhiều lớp khác [i. e. cho phép đa thừa kế]
Do đó, khi chúng ta kế thừa nhiều lớp từ lớp khác, các kiểu mẫu kế thừa khác nhau có thể được hình thành
Tuy nhiên, một kiểu kế thừa trong các ngôn ngữ lập trình giống như hình kim cương gây ra sự mơ hồ trong lời gọi phương thức của lớp cha, thường được gọi là vấn đề kim cương
Trong hướng dẫn này, chúng ta sẽ tìm hiểu vấn đề kim cương thực sự là gì và cách chúng ta có thể giải quyết nó bằng Python
Vấn đề kim cương là gì?
Vấn đề kim cương xảy ra khi hai lớp có một lớp cha chung và một lớp khác có cả hai lớp đó làm lớp cơ sở
ITrong kiểu triển khai kế thừa này, nếu lớp
>>> D.__mro__
[, , , , ]
4 và lớp >>> D.__mro__
[, , , , ]
5 ghi đè [bất kỳ] cùng một phương thức của lớp >>> D.__mro__
[, , , , ]
6 và thể hiện của lớp >>> D.__mro__
[, , , , ]
7 gọi phương thức đó, thì nó trở nên mơ hồ đối với các ngôn ngữ lập trình, cho dù chúng ta có muốn gọi phương thức bị ghi đè từ lớp >>> D.__mro__
[, , , , ]
4 hay không Ví dụ
class A:
def display[self]:
print["This is class A"]
class B[A]:
def display[self]:
print["This is class B"]
class C[A]:
def display[self]:
print["This is class C"]
class D[B, C]:
pass
obj = D[]
obj.display[]
Trong ví dụ mã này, chúng tôi đang gọi phương thức
# define base class0 trên thể hiện của lớp
# define a method
class Base:
def method[self]:
print["method called from Base"]
# define a subclass, inheriting from Base
# override the method
class Subclass[Base]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
7. Vì lớp >>> D.__mro__
[, , , , ]
7 kế thừa cả lớp >>> D.__mro__
[, , , , ]
4 và lớp >>> D.__mro__
[, , , , ]
5, không biết lớp nào trong số # define base class0 bị ghi đè sẽ được trình thông dịch Python gọi
# define a method
class Base:
def method[self]:
print["method called from Base"]
# define a subclass, inheriting from Base
# override the method
class Subclass[Base]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , ]
method called from Subclass
Làm cách nào để giải bài toán kim cương bằng Python?
Do thứ tự giải quyết phương thức [
>>> D.__mro__
[, , , , ]
5] trong Python, sự mơ hồ của vấn đề kim cương trong Python trở nên không liên quanThứ tự phân giải phương thức trong Python là thứ tự mà một phương thức được tìm kiếm trong phân cấp lớp, trong trường hợp kế thừa
Chúng ta có thể xem thứ tự này bằng cách truy cập thuộc tính
>>> D.__mro__
[, , , , ]
5 trên các lớp>>> D.__mro__
[, , , , ]
Như chúng ta có thể thấy, trong đầu ra
>>> D.__mro__
[, , , , ]
5 của lớp >>> D.__mro__
[, , , , ]
7, lớp >>> D.__mro__
[, , , , ]
4 đứng trước lớp >>> D.__mro__
[, , , , ]
5. Do đó, nếu gọi phương thức # define base class0 trên lớp
# define a method
class Base:
def method[self]:
print["method called from Base"]
# define a subclass, inheriting from Base
# override the method
class Subclass[Base]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
7, trình thông dịch Python sẽ tìm và gọi phương thức # define base class0 của lớp
# define a method
class Base:
def method[self]:
print["method called from Base"]
# define a subclass, inheriting from Base
# override the method
class Subclass[Base]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
4 Một vấn đề khá rắc rối, vấn đề Kim cương có hai điều. MRO và khái niệm kế thừa, cụ thể hơn là đa thừa kế. Nhưng hãy xác định từng cái một và xem chúng được làm từ gì
MRO
MRO, viết tắt của Thứ tự giải quyết phương pháp. Nó được sử dụng trong thừa kế và nó đại diện cho thứ tự của các lớp trong đó một phương thức cụ thể đang được tìm kiếm. MRO càng quan trọng hơn trong Python, vì Python có các tính năng và hỗ trợ đầy đủ một trường hợp kế thừa cụ thể, được gọi là đa kế thừa
Đa kế thừa đại diện cho trường hợp đặc biệt, nhưng rất có thể xảy ra và khá phổ biến khi một lớp có thể kế thừa từ nhiều lớp
Trường hợp Python có liên quan, MRO chỉ định rằng phương thức đang được tìm kiếm ở những nơi sau
- lớp của đối tượng;
- siêu hạng ngay lập tức. Trong trường hợp có nhiều hơn một, nó sẽ được tìm kiếm từ trái sang phải, theo thứ tự mà chúng được nhà phát triển khai báo;
Việc tìm kiếm tiếp tục theo mô hình được mô tả ở trên cho đến khi đạt đến lớp cơ sở. Trong trường hợp phương pháp vẫn chưa được tìm thấy, một ngoại lệ sẽ được đưa ra
Hãy xem MRO hoạt động trên một ví dụ rất đơn giản
# define base class
# define a method
class Base:
def method[self]:
print["method called from Base"]
# define a subclass, inheriting from Base
# override the method
class Subclass[Base]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , ]
method called from Subclass
Chúng ta đã định nghĩa một lớp
# define base class no. 13 và một lớp
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
# define base class no. 14 kế thừa từ nó. Cả hai lớp đều có cách triển khai riêng của phương thức
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
# define base class no. 10
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
Trong Python, có một phương thức tên là
# define base class no. 11 có thể được gọi trên chính lớp đó và nó sẽ trả về một danh sách thứ tự các lớp trong đó các phương thức đang được tìm kiếm. Trong trường hợp của chúng tôi, như đã mô tả trước đó, phương thức đầu tiên được tìm kiếm trong lớp
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
# define base class no. 14, sau đó trong lớp
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
# define base class no. 13 và cuối cùng, lớp
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
# define base class no. 14 là lớp cuối cùng tìm kiếm phương thức
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
Lớp
# define base class no. 14 xuất hiện trong danh sách này mặc dù nó không được chúng tôi định nghĩa trong mô-đun của mình, bởi vì tất cả các lớp trong Python đều kế thừa từ lớp
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
# define base class no. 14 theo mặc định, trừ khi được chỉ định khác
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
Cuối cùng, phương thức được tìm thấy trong lớp
# define base class no. 14, nó được truy cập và gọi và như vậy, thông báo mà chúng tôi đang mong đợi là thông báo mà chúng tôi nhận được
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
đa thừa kế
Python cho phép một lớp kế thừa từ nhiều lớp. Xem xét ví dụ sau
# define base class no. 1
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
In ra MRO cho
# define base class no. 14 của chúng tôi, chúng tôi thấy rằng trước tiên phương thức này đang được tìm kiếm trong
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
# define base class no. 14, sau đó nó đang được tìm kiếm [nếu nó chưa được tìm thấy] trong các lớp
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
20 và >>> D.__mro__
[, , , , ]
21, theo đúng thứ tự >>> D.__mro__
[, , , , ]
2Chúng tôi đang tiến gần đến việc xác định điểm nổi bật của bài viết này. vấn đề kim cương. Hãy xem đó là tất cả những gì
Vấn đề kim cương
Tên xuất phát từ cách giải thích trực quan của kịch bản sau
Chúng tôi có một lớp
# define base class no. 13, 2 lớp khác kế thừa từ nó và lớp thứ tư kế thừa từ 2 lớp trước
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
5Điều này tạo nên thứ bậc thừa kế hình Kim Cương của bốn hạng nói trên
Hãy xem "viên kim cương" này trông như thế nào từ phối cảnh mã
>>> D.__mro__
[, , , , ]
6Vì
# define base class no. 14 kế thừa từ cả
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
25 và >>> D.__mro__
[, , , , ]
26 và có một triển khai của >>> D.__mro__
[, , , , ]
27 trong mỗi lớp này, người ta có thể thấy vấn đề kim cương hình thành. lớp nào trong hai lớp sẽ cung cấp phương thức mà # define base class no. 14 của chúng ta yêu cầu?
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
0MRO một lần nữa đóng vai trò quyết định trong việc kêu gọi
>>> D.__mro__
[, , , , ]
27. Vì # define base class no. 14 của chúng tôi không có triển khai
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
27 của riêng nó, nên tất cả tùy thuộc vào MRO [và nhà phát triển] để quyết định lớp nào sẽ gọi >>> D.__mro__
[, , , , ]
27Vì vậy, trước tiên,
# define base class no. 14 đã được tìm kiếm phương pháp. Python rõ ràng là không thể tìm thấy nó, vì vậy nó đã tăng một bậc trong hệ thống phân cấp kim cương. Ở cấp độ này, nó không chỉ tìm thấy một mà là hai lớp. Python sau đó xem xét thứ tự mà chúng được chỉ định.
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
54, vậy đó là thứ tự tìm kiếm các lớp. Vì vậy, >>> D.__mro__
[, , , , ]
55 là dòng tiếp theo và vì >>> D.__mro__
[, , , , ]
27 của chúng tôi đã được tìm thấy trong lớp đó, đó là nơi dừng tìm kiếm và >>> D.__mro__
[, , , , ]
57 được gọi, do đó, dòng đầu ra mà chúng tôi nhận được. >>> D.__mro__
[, , , , ]
58Một khía cạnh rất quan trọng cần lưu ý là chữ ký phương thức trong các lớp phải khớp với phương thức được gọi trong lớp con. Để mở rộng thêm về vấn đề này, MRO hướng dẫn Python cách tìm tên của phương thức. Nó không tính đến chữ ký của nó. Nếu lớp con gọi phương thức với một tập hợp các đối số không khớp với chữ ký của phương thức được tìm thấy đầu tiên, nó sẽ đưa ra một Ngoại lệ
>>> D.__mro__
[, , , , ]
9Ở đây chúng ta thấy rằng
# define base class no. 14 đã gọi phương thức với một đối số số, phù hợp với việc thực hiện của
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
27 từ >>> D.__mro__
[, , , , ]
61. Tuy nhiên, vì chúng tôi đã xác định thứ tự thừa kế là >>> D.__mro__
[, , , , ]
62, nên đó là >>> D.__mro__
[, , , , ]
55 trong đó >>> D.__mro__
[, , , , ]
27 sẽ được tìm thấy đầu tiên và do việc triển khai >>> D.__mro__
[, , , , ]
27 của chính >>> D.__mro__
[, , , , ]
55 có chữ ký khác với những gì mà # define base class no. 14 đã yêu cầu, nên chúng tôi sẽ ném một
# define a method
class Base1:
def method[self]:
print["method called from Base1"]
# define base class no. 2
# define same method
class Base2:
def method[self]:
print["method called from Base2"]
# define a subclass, inheriting from Base1 and Base2
# override the method
class Subclass[Base1, Base2]:
def method[self]:
print["method called from Subclass"]
# instantiate the subclass
b = Subclass[]# print out the MRO for the subclass
print[Subclass.mro[]]# call the method
b.method[]Output:
[, , , ]
method called from Subclass
>>> D.__mro__
[, , , , ]
68 vào >>> D.__mro__
[, , , , ]
8Mặc dù
>>> D.__mro__
[, , , , ]
61 đã cung cấp triển khai >>> D.__mro__
[, , , , ]
27 khớp với chữ ký được yêu cầu, nhưng chính thứ tự kế thừa cuối cùng đã hướng dẫn [thông qua MRO] Python chuyển sang >>> D.__mro__
[, , , , ]
55, kết thúc bằng ngoại lệ mà chúng ta vừa chứng kiến. Chỉ cần thay thế >>> D.__mro__
[, , , , ]
54 bằng dòng mã sau. >>> D.__mro__
[, , , , ]
54 giải quyết vấn đềTôi sẽ chỉ kết thúc bài viết này tại đây, vì nó đã đạt được mục đích của nó và đó là đã trình bày bài toán Kim cương — và một số giải pháp tiềm năng cho nó — một cách rõ ràng nhất có thể. Vì vậy, chúc bạn mã hóa vui vẻ, giữ an toàn và cho đến lần sau
Deck là một kỹ sư phần mềm, người cố vấn, nhà văn và đôi khi là một giáo viên. Với hơn 12 năm kinh nghiệm trong lĩnh vực công nghệ phần mềm, anh ấy hiện là người ủng hộ thực sự cho ngôn ngữ lập trình Python trong khi niềm đam mê của anh ấy là giúp mọi người mài giũa kỹ năng Python — và lập trình nói chung —. Bạn có thể truy cập Deck trên Linkedin, Facebook, Twitter và Discord. Deck451#6188, cũng như theo dõi bài viết của anh ấy tại đây trên Medium
Thêm nội dung tại PlainEnglish. io. Đăng ký nhận bản tin hàng tuần miễn phí của chúng tôi. Theo dõi chúng tôi trên Twitter và LinkedIn. Kiểm tra Sự bất hòa trong cộng đồng của chúng tôi và tham gia Tập thể tài năng của chúng tôi