HIỂU NHANH: Lập trình Hướng đối tượng PYTHON

Python cho phép viết chương trình theo một số mô hình (như lập trình hướng thủ tục, lập trình hàm, lập trình hướng đối tượng).

Trong đó,

Lập trình hướng đối tượng là một trong những mô hình lập trình sử dụng rộng rãi nhất.

Nó được dựa trên các đối tượng — thực thể chứa dữ liệu thành viên gọi là thuộc tính (attributes) và các chức năng gọi là methods.

Đối tượng là một thể hiện (instance) của lớp (class).

Nói cách khác, các class, chủ yếu là xác định được cấu trúc và làm mẫu để tạo ra các đối tượng.

Các class có định nghĩa phương thức nhưng cũng có thể chứa dữ liệu chung cho tất cả các thể hiện của chúng.

Lập trình Hướng đối tượng trong Python

Lập trình Hướng đối tượng trong Python

Bài này là bài Hướng dẫn cơ bản về Lập trình hướng đối tượng Python, nó giải thích làm thế nào để tạo ra các class và sử dụng chúng để tạo đối tượng của chúng.

Đặc biệt, bài viết này bao gồm:

Bài viết này không bao gồm tất cả các chi tiết về các chủ đề Lập trình hướng đối tượng.

Nhưng nó có thể cung cấp một nền tảng tốt để bạn bắt đầu học Python và lập trình chương trình theo mô hình hướng đối tượng với Python.

#1. Tạo Class trong Python

Chúng ta định nghĩa một class Python với từ khóa class, theo sau là tên của class, dấu hai chấm : và khai triển cụ thể của class:

classMyClass:
    pass

Khi bạn tạo một class mà không có khai triển gì, nó sẽ gây ra lỗi.

Để tránh lỗi này thì mình sử dụng từ khóa pass.

Theo qui ước, tên của class trong Python được đặt theo ThePascalCase.

  • Pascal Case có nghĩa là từ đầu tiên của tất cả các từ phải được viết Hoa, ví dụ: MyClass, UserAcount, AdminAcount

  • Đọc thêm về những kiểu đặt tên tại đây .

Bây giờ,

Hãy thử tạo một thể hiện của class MyClass chúng ta vừa tạo.

# Tạo classclassMyClass:
    pass
# Tạo đối tượng từ class MyClassa = MyClass()
print(a)

Kết quả :

< __main__. MyClass object at 0x0084 F790 >

Câu lệnh a = MyClass() tạo một thể hiện của class MyClass và gán tham chiếu cho nó cho một biến mới là a.

Chúng ta có thể lấy được kiểu dữ liệu của MyClass,

Để làm được việc này Python có một hàm tích hợp (built-in function) là type().

Hoặc sử dụng thuộc tính.__class__.

type(a)

#

a.__class__

#

Và thông qua thuộc tính .__class__, chúng ta cũng có thể lấy được tên của nó.

a.__class__.__name__
# MyClass

Nhân tiện, hãy lưu ý là các class trong Python cũng là các đối tượng, nhưng chúng là thể hiện của class type.

print(type(MyClass))

#

Định nghĩa phương thức trong class

Phương thức trong class cũng giống như hàm.

Tuy nhiên, mỗi phương thức trong class đều phải có ít nhất một tham số, tham số đầu tiên trong class tương tự như this trong các ngôn ngữ khác.

Theo quy ước, trong Python, tham số này được gọi là self.

Dĩ nhiên, bạn có thể đặt tên bất kỳ, nhưng sử dụng self theo mặc định sẽ dễ hiểu hơn.

Khi gọi phương thức thì không cần truyền đối số cho self.

Và, một trong những phương thức quan trọng nhất mà chúng ta thường định nghĩa là .__init __().

Phương thức .__init__() tương tự contructor trong Java.

Phương thức này sẽ được gọi sau khi một thể hiện của class được tạo.

Nó khởi tạo các thành viên trong class.

Hãy xem ví dụ để hiểu rõ hơn:

classMyClass:
    def__init__(self,arg_1,arg_2,arg_3):
        print(f'Một biểu lộ của{type(self).__name__}được tạo : ')
        print(f'arg _1 :{arg_1}, arg_2 :{arg_2}, arg_3 :{arg_3}')

Chúng ta đã tạo một ví dụ về MyClass, để xem những gì sẽ xảy ra .

  • Phương thức .__init __() của chúng ta có ba đối số (arg_1, arg_2 và arg_3)

  • Hãy nhớ là tất cả chúng ta không cần truyền đối số cho self

Do đó, tất cả chúng ta sẽ phân phối cho nó ba đối số khi chúng tôi khởi tạo đối tượng :

# Khởi tạo đối tượng# Truyền 3 đối sốa = MyClass(1,2,3)

Kết quả :

Một biểu lộ của MyClass được tạo :arg_1 : 1, arg_2 : 2, arg_3 : 3

Đây là những gì vừa xảy ra :

  • Một thể hiện (đối tượng) của MyClass vừa được tạo

  • Phương thức. __init__ ( ) được gọi tự động hóa
  • 3 đối số (1, 2, 3) chúng ta truyền khi khởi tạo đối tượng được truyền vào .__init__()

  • .__init__() tiếp tục thực thi 2 lệnh print. Nó lấy tên class bằng type(self).__name__

Bây giờ chúng ta có một class, phương thức .__init__() của nó và một thể hiện của class này.

Data Attributes

Chúng ta đã có class, bây giờ, hãy tạo cho nó một ít dữ liệu.

Chúng ta khởi tạo và định nghĩa, và cũng có thể thay đổi dữ liệu được gán trong .__init__() hoặc bất cứ phương thức nào

Ví dụ:

classMyClass :
    def__init__(self,x,y,z ) :
        self. x = x
        self. _y = y
        self. __z = z

Bây giờ, tất cả chúng ta có ba data attributes :

  • x lấy giá trị của x

  • _y lấy giá trị của y

  • __z lấy giá trị của z

Bạn cũng hoàn toàn có thể viết ngắn gọn hơn như thế này :

classMyClass:
    def__init__(self,x,y,z):
        self.x,self._y,self.__z = x,y,z

Bạn có để ý dấu gạch dưới _ mình thêm vào trong các biến không?

Mục đích của việc này là thiết lập mức độ hiển thị của biến.

  • Các thuộc tính không có dấu gạch dưới ở đầu (như .x) thường có thể được gọi và sửa đổi từ bên ngoài đối tượng.

  • Các thuộc tính có 1 dấu gạch dưới ở đầu (như ._y) cũng có thể được gọi và sửa đổi từ bên ngoài đối tượng. Tuy nhiên, nó chỉ được gọi và sửa đổi thông qua các các phương thức và thuộc tính của class đó.

  • Các thuộc tính có 2 dấu gạch dưới ở đầu (như .__z) sẽ có tên được thay đổi (trong trường hợp này là ._MyClass__z) trong quy trình được gọi là name mangaling. Chúng cũng có thể được gọi và sửa đổi từ bên ngoài đối tượng với tên mới. Tuy nhiên, nó chỉ được gọi và sửa đổi thông qua các các phương thức, thuộc tính trong class đó

Các data attributes của các đối tượng Python thường được lưu trữ trong dictionaries có tên là .__dict__, cũng là thuộc tính của đối tượng.

Tuy nhiên, nó có thể lưu trữ dữ liệu ở những nơi khác. Chúng ta có thể lấy .__dict__ bằng cách gọi trực tiếp hoặc bằng hàm vars():

# Khởi tạo đối tượnga = MyClass(2,4,6)
# In dữ liệuprint(vars(a))
print(a.__dict__)

Kết quả :

{ ' x ' : 2, ' _y ' : 4, ' _MyClass__z ' : 6 }{ ' x ' : 2, ' _y ' : 4, ' _MyClass__z ' : 6 }

Tìm hiểu thêm:

Thao tác với Dữ liệu trong Python

Key '_MyClass__z', ở đó thay vì '__z bởi vì nó đã trải qua quá trình name magaling.

Chúng ta có thể sử dụng .__dict__ như bất kỳ dictionaries nào khác.

Và đây là cách thông thường để lấy và thay đổi các giá trị được liên kết với các thuộc tính dữ liệu:

  • Lấy giá trị của x

print(a.x)


Kết quả :

2

  • Sửa đổi giá trị của x

a.x = 10print(a.x)

Kết quả :

10
  • Lấy giá trị của _y

print(a._y)

Kết quả :

  • Sửa đổi giá trị của _y

a._y = 20print(a._y)

Kết quả :

20
  • Lấy giá trị của __z

print(a.__z)

Kết quả :

Traceback ( most recent call last ) :

File "C:/Users/Admin/PycharmProjects/Demo2/demo1.py", line 9, in

print ( a. __z )AttributeError : ' MyClass ' object has no attribute ' __z '

Bởi vì __z đã được đổi tên (qua quá trình name mangaling), chúng ta không còn có biến __z nữa, vậy nên truy cập sẽ gây ra lỗi.

print(vars(a))

Kết quả :

{ ' x ' : 2, ' _y ' : 4, ' _MyClass__z ' : 6 }

Instance Methods

Bây giờ, tất cả chúng ta sẽ thử tạo instance method trong class xem thế nào nhé .

  • .set_z() để sửa đổi .__z

  • .get__z() để trả về giá trị của .__z

Hãy nhớ là tham số đầu tiên của mỗi instance method (được gọi là self theo quy ước) đề cập đến chính đối tượng đó, nhưng chúng ta không cần cung cấp khi gọi.

classMyClass:
    def__init__(self,x,y,z):
        self.x,self._y,self.__z = x,y,z

    # Sửa đổi giá trị của __zdefset_z(self,value):
        self.__z = value

    # Lấy giá trị của __zdefget_z(self):
        returnself.__z


b = MyClass(2,4,6)

Các phương thức .get_z().set_z() cung cấp interface thông thường để truy xuất và sửa đổi giá trị của .__z:

  • Lấy giá trị của .__z

value_z = b.get_z()
print(value_z)

Kết quả :

6
  • Sửa đổi giá trị của .__z

b.set_z(10)
print(vars(b))

Kết quả :

{ ' x ' : 2, ' _y ' : 4, ' _MyClass__z ' : 10 }

.get_z().set_z() có thể mang lại chức năng bổ sung như kiểm tra tính hợp lệ của dữ liệu.

Các phương thức như vậy cho phép chúng ta đạt được tính đóng gói, (encapsulation), đây là một trong những khái niệm chính trong lập trình hướng đối tượng.

Tìm hiểu thêm:

09 Khái niệm Lập trình hướng đối tượng trong Java
Học Lập trình Java miễn phí tại nhà.Hoặctại nhà .

Properties

Một cách khác để truy cập vào và thay đổi các data attributes được sử dụng là properties.

Cách làm này để đạt được tính dễ đọc (Còn gọi là Pythonic)

Chúng đóng gói các phương thức getter, setterdeleters — nhưng cư xử như data attributes bình thường.

Đây là cách triển khai thuộc tính .z có chức năng tương tự như .get_z().set_z():

classMyClass:
    def__init__(self,x,y,z):
        self.x,self._y,self.__z = x,y,z

    @ propertydefz(self):
        returnself.__z

    @ z. setterdefz(self,value):
        self.__z = value


b = MyClass(2,4,8)

Đây là cách chúng ta có thể truy cập và sửa đổi .__z với thuộc tính .z tương ứng:

  • Truy cập .__z

print(b.z)

Kết quả:

8
  • Sửa đổi giá trị của .__z

b.z = 20print(b.z)

Kết quả :

20

Code như thế này chắc như đinh ngắn và dễ đọc hơn đúng không ?

Static Method và Static Method

Ngoài các instance methodinstance properties, các class có thể có các Class MethodStatic Method.

Để hiểu rõ hơn, hãy thêm ba phương thức f, g, h vào MyClass:

classMyClass:
    def__init__(self,x,y,z):
        self.x,self._y,self.__z = x,y,z

    deff(self,arg):
        print(' Instance method f được gọi ')
        print(f'instance :{self}')
        print(f'instance attributes :\ n {vars(self)}')
        print(f'class :{type(self)}')
        print(f'arg :{arg}')\

    @ classmethoddefg(cls,arg):
        print(' class method g được gọi ')
        print(f'cls :{cls}')
        print(f'arg :{arg}')
    @ staticmethoddefh(arg):
        print(' static method h được gọi ')
        print(f'arg :{arg}')


c = MyClass(2,4,6)

Phương thức .f() là một instance method.

Các instance method cũng phải có đối số đầu tiên (self) đề cập đến chính đối tượng.

Chúng có thể tự truy cập:

  • Vào đối tượng, các thuộc tính dữ liệu của đối tượng bằng vars(self) hoặc self.__dict__

  • Vào class tương ứng với đối tượng với type(self) hoặc self.__class__

  • Vào những đối số của riêng chúng .

Phương thức .g() được định nghĩa bằng @classmethod.

Điều đó làm cho nó trở thành một class method.

Mỗi phương class method phải có tham số đầu tiên tham chiếu đến class, được gọi là cls (theo quy ước).

Như trong trường hợp của các instance method, chúng ta không cần cung cấp đối số cho nó khi gọi.

Các instance method có thể truy cập vào class với cls và các đối số riêng.

Phương thức .h() được định nghĩa bằng @staticmethod. Điều này làm cho nó trở thành một static method.

Điều này có nghĩa là các static method có thể truy cập chỉ các đối số của riêng chúng.

Đây là cách các instance method thường được gọi trong Python:

c.f(' my-argument ')

Kết quả:

Instance method f được gọiinstance : < __main__. MyClass object at 0x039951 B0 >instance attributes :{ ' x ' : 2, ' _y ' : 4, ' _MyClass__z ' : 6 }

class:

arg : my-argument

Các class method và static method có thường được gọi thông qua class.

Điều này có nghĩa là bạn không cần phải khởi tạo đối tượng mà vẫn truy cập được.

  • Gọi class method g

MyClass.g(' my-argument ')

Kết quả :

class method g được gọi

cls:

arg : my-argument
  • Gọi static method h

MyClass.h(' my-argument ')

Kết quả :

static method h được gọiarg : my-argument

Hãy nhớ là chúng ta không cần truyền đối số tương ứng với tham số đầu tiên của một class method.

Tuy nhiên, các class method và static method cũng có thể được gọi thông qua đối tượng, như thế này:

c.g(' my-argument ')

Kết quả :

class method g được gọi

cls:

arg : my-argument

Và ,

c.h(' my-argument ')

Kết quả :

static method h được gọiarg : my-argument

Khi chúng ta gọi c.gc.h, nếu không có instance member nào có tên như vậy, nó sẽ tìm kiếm đến class member và static member.

Inheritance

Kế thừa (Inheritance) là một tính năng quan trọng khác của lập trình hướng đối tượng.

Nó có một khái niệm trong đó:

  • Một class được gọi là subclass (hoặc class dẫn xuất) sẽ có được (kế thừa) dữ liệu, chức năng từ một số class khác được gọi là super class (hoặc base class).

Trong Python, tất cả các class đều kế thừa từ class được dựng sẵn là object.

Tuy nhiên, chúng ta có thể định nghĩa hệ thống phân cấp thừa kế của các class riêng của chúng ta cho phù hợp.

Ví dụ: Chúng ta sẽ tạo một class mới gọi là MyOtherClass kế thừa MyClass:

classMyOtherClass(MyClass):

    def__init__(self,u,v,w,x,y,z):
        super().__init__(x,y,z)
        self.__u,self.__v,self.__w = u,v,w

    deff_(self,arg):
        print(' instance method f_ được gọi ')
        print(f'instance :{self}')
        print(f'instance attributes :\ n {vars(self)}')
        print(f'class :{type(self)}')
        print(f'arg :{arg}')

d = MyOtherClass(1,2,4,8,16,32)

MyOtherClass có các thành viên của MyClass: .x, ._y, .__z.f().

Các data member của super class là: .x, ._y.__z được khởi tạo với câu lệnh super().__init__(x, y, z) gọi đến phương thức .__ init __() của super class.

MyOtherClass cũng có các data member riêng là: .__u, .__v, .__w.f_().

Chúng ta sẽ nhận được các data member với vars():

print(vars(d))

Kết quả :

{ ' x ' : 8, ' _y ' : 16, ' _MyClass__z ' : 32, ' _MyOtherClass__u ' : 1, ' _MyOtherClass__v ' : 2, ' _MyOtherClass__w ' : 4 }

Chúng ta hoàn toàn có thể gọi những phương pháp từ cả super class và subclass :

  • Gọi phương thức f của super class

d.f(' some-argument ')

Kết quả :

Instance method f được gọiinstance : < __main__. MyOtherClass object at 0x010 E5310 >instance attributes :{ ' x ' : 8, ' _y ' : 16, ' _MyClass__z ' : 32, ' _MyOtherClass__u ' : 1, ' _MyOtherClass__v ' : 2, ' _MyOtherClass__w ' : 4 }

class:

arg : some-argument
  • Gọi phương thức f_ của subclass

d.f_(' some-argument ')

Kết quả :

instance method f_ được gọiinstance : < __main__. MyOtherClass object at 0x01575310 >instance attributes :{ ' x ' : 8, ' _y ' : 16, ' _MyClass__z ' : 32, ' _MyOtherClass__u ' : 1, ' _MyOtherClass__v ' : 2, ' _MyOtherClass__w ' : 4 }

class:

rg : some-argument

Tuy nhiên, gọi như vậy, nếu subclass và super class có data member nào trùng tên thì subclass sẽ được ưu tiên.

Chúc mừng bạn đã biết cơ bản về Lập trình hướng đối tượng trong Python

Lập trình hướng đối tượng là một trong những mô hình lập trình được Python hỗ trợ. Đây cũng là mô hình lập trình được sử dụng phổ biến nhất.

Ngoài ra, vẫn có những mô hình lập trình khác có ưu điểm trong một số trường hợp khác.

Bài viết này mình đã minh họa cách sử dụng các class Python và tạo các chương trình hướng đối tượng cơ bản.

Có có nhiều thứ về lập trình hướng đối tượng chưa được giải thích rõ như:

  • Methods .__repr__() and .__str__()

  • Method .__new__()

  • Operators
  • Methods .__getattribute__().__getattr__().__setattr__(), và .__delattr__()

  • Generators
  • Callability
  • Creating sequences
  • Descriptors
  • Context managers
  • Abstract classes and members
  • Multiple inheritance
  • Sử dụng super()

  • Copying
  • Pickling
  • Slots
  • Class decorators
  • Data classes và nhiều hơn nữa .

Lập trình hướng đối tượng rất quan trọng trong sự nghiệp lập trình viên (Không chỉ lập trình viên Python).

Vì thế, nếu bạn muốn Học Python để tìm kiếm một sự nghiệp với Python thì hãy học và luyện tập sử dụng mô hình này thật kỹ càng.rất quan trọng trong sự nghiệp lập trình viên ( Không chỉ lập trình viên Python ). Vì thế, nếu bạn muốnđể tìm kiếm một sự nghiệp với Python thì hãy học và rèn luyện sử dụng quy mô này thật kỹ càng .

Chúc bạn thành công xuất sắc !

HỌC VIỆN ĐÀO TẠO CNTT NIIT – ICT HÀ NỘI

Dạy học Lập trình chất lượng cao ( Since 2002 ). Học làm Lập trình viên. Hành động ngay !

Đc : Tầng 3, 25T2, N05, Nguyễn Thị Thập, CG cầu giấy, TP. Hà Nội

SĐT : 02435574074 – 0914939543 – 0353655150

E-Mail : [email protected]

Fanpage : https://facebook.com/NIIT.ICT/

 

# niit # niithanoi # niiticthanoi # hoclaptrinh # khoahoclaptrinh # hoclaptrinhjava # hoclaptrinhphp # python # java # php

Kết quả : Kết quả :