Hướng dẫn what is the difference between a class and an instance of a class python? - sự khác biệt giữa một lớp và một thể hiện của một lớp python là gì?

Ảnh của Christopher Gower trên unplash

Sự khác biệt giữa các biến lớp và trường hợp được giải thích.

Các biến về cơ bản là các ký hiệu đứng trong một giá trị mà chúng tôi sử dụng trong một chương trình. Lập trình hướng đối tượng cho phép các biến được sử dụng ở cấp độ lớp hoặc cấp độ thể hiện. Mục đích của bài viết này là có sự khác biệt rõ ràng giữa các loại biến được cung cấp bởi mô hình đối tượng Python, và tiếp tục đến với

Khi bạn viết một khối lớp, bạn tạo các thuộc tính lớp (hoặc biến lớp). Tất cả các tên bạn gán trong khối lớp, bao gồm các phương thức bạn xác định với def trở thành thuộc tính lớp.

Sau khi một phiên bản lớp được tạo, bất cứ điều gì có tham chiếu đến phiên bản đều có thể tạo các thuộc tính thể hiện trên đó. Các phương thức bên trong, ví dụ "hiện tại" hầu như luôn luôn bị ràng buộc với tên self, đó là lý do tại sao bạn nghĩ về những thứ này là "biến tự". Thông thường trong thiết kế hướng đối tượng, mã được gắn vào một lớp được cho là có quyền kiểm soát các thuộc tính của các phiên bản của lớp đó, do đó, hầu như tất cả các gán thuộc tính thể hiện được thực hiện bên trong các phương thức, sử dụng tham chiếu đến thể hiện trong tham số self của Phương pháp.

Các thuộc tính lớp thường được so sánh với các biến tĩnh (hoặc phương thức) như được tìm thấy trong các ngôn ngữ như Java, C#hoặc C ++. Tuy nhiên, nếu bạn muốn nhắm đến sự hiểu biết sâu sắc hơn, tôi sẽ tránh nghĩ về các thuộc tính của lớp là "giống nhau" với các biến tĩnh. Mặc dù chúng thường được sử dụng cho cùng một mục đích, nhưng khái niệm cơ bản khá khác nhau. Thông tin thêm về điều này trong phần "Nâng cao" bên dưới dòng.

Một ví dụ!

class SomeClass:
    def __init__(self):
        self.foo = 'I am an instance attribute called foo'
        self.foo_list = []

    bar = 'I am a class attribute called bar'
    bar_list = []

Sau khi thực hiện khối này, có một lớp

instance = SomeClass()
1, với 3 thuộc tính lớp:
instance = SomeClass()
2,
instance = SomeClass()
3 và
instance = SomeClass()
4.

Sau đó, chúng tôi sẽ tạo một thể hiện:

instance = SomeClass()

Khi điều này xảy ra, phương thức

instance = SomeClass()
2 của ____ 11 được thực thi, nhận phiên bản mới trong tham số self của nó. Phương thức này tạo ra hai thuộc tính thể hiện:
instance = SomeClass()
8 và
instance = SomeClass()
9. Sau đó, trường hợp này được gán vào biến
print instance.bar
0, do đó, nó bị ràng buộc với một điều với hai thuộc tính thể hiện đó:
instance = SomeClass()
8 và
instance = SomeClass()
9.

But:

print instance.bar

gives:

I am a class attribute called bar

Làm sao chuyện này lại xảy ra? Khi chúng tôi cố gắng truy xuất một thuộc tính thông qua cú pháp DOT và thuộc tính không tồn tại, Python đã trải qua một loạt các bước để thử và đáp ứng yêu cầu của bạn. Điều tiếp theo nó sẽ cố gắng là xem xét các thuộc tính lớp của lớp thể hiện của bạn. Trong trường hợp này, nó đã tìm thấy một thuộc tính

instance = SomeClass()
3 trong
instance = SomeClass()
1, vì vậy nó đã trả lại điều đó.

Đó cũng là cách mà phương thức gọi hoạt động bằng cách này. Ví dụ, khi bạn gọi

print instance.bar
5,
print instance.bar
6 không có thuộc tính có tên
print instance.bar
7. Nhưng lớp của
print instance.bar
6 cũng vậy và nó bị ràng buộc với một đối tượng phương thức. Đối tượng phương thức đó được trả về bởi bit
print instance.bar
9 và sau đó bit
I am a class attribute called bar
0 gọi phương thức với đối số
I am a class attribute called bar
1.

Cách thức này hữu ích là tất cả các trường hợp của

instance = SomeClass()
1 sẽ có quyền truy cập vào cùng một thuộc tính
instance = SomeClass()
3. Chúng tôi có thể tạo một triệu trường hợp, nhưng chúng tôi chỉ cần lưu trữ một chuỗi đó trong bộ nhớ, bởi vì tất cả chúng đều có thể tìm thấy nó.all instances of
instance = SomeClass()
1 will have access to the same
instance = SomeClass()
3 attribute. We could create a million instances, but we only need to store that one string in memory, because they can all find it.

Nhưng bạn phải cẩn thận một chút. Hãy xem các hoạt động sau:

sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list

Bạn nghĩ những gì bản in này?

[1]
[2, 20]
[10]
[2, 20]

Điều này là do mỗi trường hợp có bản sao riêng của nó là

instance = SomeClass()
9, vì vậy chúng được thêm vào một cách riêng biệt. Nhưng tất cả các trường hợp chia sẻ quyền truy cập vào cùng một
instance = SomeClass()
4. Vì vậy, khi chúng tôi đã làm
I am a class attribute called bar
6, nó đã ảnh hưởng đến
I am a class attribute called bar
7, mặc dù
I am a class attribute called bar
7 vẫn chưa tồn tại! Và tương tự
I am a class attribute called bar
9 đã ảnh hưởng đến
instance = SomeClass()
4 được lấy qua
sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
1. Đây thường không phải là những gì bạn muốn.


Nghiên cứu nâng cao theo sau. :)

Để thực sự Grok Python, đến từ các ngôn ngữ oo được đánh máy truyền thống như Java và C#, bạn phải học cách suy nghĩ lại các lớp một chút.

Trong Java, một lớp học không thực sự là một thứ theo đúng nghĩa của nó. Khi bạn viết một lớp, bạn sẽ tuyên bố nhiều hơn một loạt những điều mà tất cả các trường hợp của lớp đó đều có điểm chung. Trong thời gian chạy, chỉ có các trường hợp (và các phương thức/biến tĩnh, nhưng đó thực sự là các biến và chức năng toàn cầu trong không gian tên liên quan đến một lớp, không liên quan gì đến OO thực sự). Các lớp là cách bạn viết ra trong mã nguồn của mình, các phiên bản sẽ như thế nào trong thời gian chạy; Chúng chỉ "tồn tại" trong mã nguồn của bạn, không phải trong chương trình đang chạy.

Trong Python, một lớp học không có gì đặc biệt. Đó là một đối tượng giống như bất cứ thứ gì khác. Vì vậy, "thuộc tính lớp" trên thực tế là chính xác giống như "thuộc tính thể hiện"; Trong thực tế, chỉ có "thuộc tính". Lý do duy nhất để vẽ một sự khác biệt là chúng ta có xu hướng sử dụng các đối tượng là các lớp khác với các đối tượng không phải là lớp. Các máy móc cơ bản là tất cả giống nhau. Đây là lý do tại sao tôi nói sẽ là một sai lầm khi nghĩ về các thuộc tính lớp là các biến tĩnh từ các ngôn ngữ khác.

Nhưng điều thực sự làm cho các lớp Python khác biệt với các lớp theo phong cách Java là giống như bất kỳ đối tượng nào khác mỗi lớp là một ví dụ của một số lớp!each class is an instance of some class!

Trong Python, hầu hết các lớp là các trường hợp của một lớp được xây dựng có tên là

sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
2. Chính lớp này kiểm soát hành vi chung của các lớp và làm cho tất cả các công cụ OO theo cách của nó. Cách OO mặc định có các phiên bản của các lớp có thuộc tính riêng của chúng và có các phương thức/thuộc tính chung được xác định bởi lớp của chúng, chỉ là một giao thức trong Python. Bạn có thể thay đổi hầu hết các khía cạnh của nó nếu bạn muốn. Nếu bạn đã từng nghe nói về việc sử dụng Metaclass, tất cả những gì đang xác định một lớp là một thể hiện của một lớp khác với
sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
2.

Điều thực sự "đặc biệt" duy nhất về các lớp (ngoài tất cả các máy móc xây dựng để làm cho chúng hoạt động theo cách mà họ làm theo mặc định), là cú pháp khối lớp, để bạn dễ dàng tạo các phiên bản là

sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
2. Đây:

class Foo(BaseFoo):
    def __init__(self, foo):
        self.foo = foo

    z = 28

gần như tương đương với những điều sau:

def __init__(self, foo):
    self.foo = foo

classdict = {'__init__': __init__, 'z': 28 }

Foo = type('Foo', (BaseFoo,) classdict)

Và nó sẽ sắp xếp cho tất cả các nội dung của

sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
5 để trở thành thuộc tính của đối tượng được tạo.

Vì vậy, sau đó, nó trở nên gần như tầm thường khi thấy rằng bạn có thể truy cập một thuộc tính lớp bằng

sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
6 dễ dàng như
sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
7. Cả
sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
8 và
sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)

sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)

print sc1.foo_list
print sc1.bar_list

print sc2.foo_list
print sc2.bar_list
9 đều là đối tượng và các đối tượng có thuộc tính. Điều này cũng giúp bạn dễ hiểu làm thế nào bạn có thể sửa đổi một lớp sau khi nó được tạo ra; Chỉ cần gán các thuộc tính của nó giống như cách bạn làm với bất kỳ đối tượng nào khác!

Trong thực tế, các trường hợp không có mối quan hệ đặc biệt đặc biệt với lớp được sử dụng để tạo ra chúng. Cách Python biết lớp nào sẽ tìm kiếm các thuộc tính không được tìm thấy trong trường hợp là thuộc tính

[1]
[2, 20]
[10]
[2, 20]
0 ẩn. Mà bạn có thể đọc để tìm hiểu lớp nào đây là một ví dụ, giống như với bất kỳ thuộc tính nào khác:
[1]
[2, 20]
[10]
[2, 20]
1. Bây giờ bạn có một biến
[1]
[2, 20]
[10]
[2, 20]
2 bị ràng buộc với một lớp, mặc dù nó có thể không có cùng tên với lớp. Bạn có thể sử dụng điều này để truy cập các thuộc tính lớp hoặc thậm chí gọi nó là để tạo thêm các trường hợp của nó (mặc dù bạn không biết đó là lớp nào!).

Và bạn thậm chí có thể gán cho

[1]
[2, 20]
[10]
[2, 20]
3 để thay đổi lớp nào đó là một ví dụ của! Nếu bạn làm điều này, không có gì đặc biệt xảy ra ngay lập tức. Nó không tan vỡ trái đất. Tất cả những gì nó có nghĩa là khi bạn tìm kiếm các thuộc tính không tồn tại trong trường hợp, Python sẽ xem xét các nội dung mới của
[1]
[2, 20]
[10]
[2, 20]
0. Vì điều đó bao gồm hầu hết các phương pháp và các phương thức thường mong đợi trường hợp họ hoạt động ở một số trạng thái nhất định, điều này thường dẫn đến lỗi nếu bạn làm điều đó một cách ngẫu nhiên và nó rất khó hiểu, nhưng nó có thể được thực hiện. Nếu bạn rất cẩn thận, điều bạn lưu trữ trong
[1]
[2, 20]
[10]
[2, 20]
0 thậm chí không phải là một đối tượng lớp; Tất cả Python sẽ làm với nó là tìm kiếm các thuộc tính trong một số trường hợp nhất định, vì vậy tất cả những gì bạn cần là một đối tượng có loại thuộc tính phù hợp (một số cảnh báo sang một bên nơi Python sẽ kén chọn những thứ là lớp hoặc trường hợp của một lớp cụ thể).

Điều đó có lẽ là đủ cho bây giờ. Hy vọng (nếu bạn thậm chí đã đọc đến nay) tôi đã không làm bạn bối rối quá nhiều. Python gọn gàng khi bạn học cách nó hoạt động. :)

Sự khác biệt giữa một lớp và thể hiện là gì?

Lớp = bản in màu xanh. Đối tượng là một thứ thực tế được xây dựng dựa trên 'bản in màu xanh' (như ngôi nhà). Một thể hiện là một bản sao ảo (nhưng không phải là bản sao thực) của đối tượng. The Object is an actual thing that is built based on the 'blue print' (like the house). An instance is a virtual copy (but not a real copy) of the object.

Một ví dụ của một python lớp là gì?

Trong ngôn ngữ lập trình Python, một thể hiện của một lớp còn được gọi là một đối tượng.Cuộc gọi sẽ bao gồm cả thành viên dữ liệu và phương thức và sẽ được truy cập bởi một đối tượng của lớp đó.an object. The call will comprise both data members and methods and will be accessed by an object of that class.

Sự khác biệt giữa biến lớp và biến thể hiện trong Python là gì?

Biến lớp là một biến xác định một thuộc tính hoặc thuộc tính cụ thể cho một lớp.Một biến thể hiện là một biến có giá trị được chỉ định cho thể hiện và được chia sẻ giữa các trường hợp khác nhau.Chúng ta có thể chia sẻ các biến này giữa lớp và các lớp con của nó.Chúng tôi không thể chia sẻ các biến này giữa các lớp.

Sự khác biệt giữa biến lớp và biến thể là gì?

Do đó, chúng được gắn với một thể hiện đối tượng cụ thể của lớp, do đó, nội dung của một biến thể hiện hoàn toàn độc lập với một thể hiện đối tượng cho những người khác.Biến lớp: Về cơ bản, nó là một biến tĩnh có thể được khai báo ở bất cứ đâu ở cấp độ lớp với tĩnh.the contents of an instance variable are totally independent of one object instance to others. Class Variable: It is basically a static variable that can be declared anywhere at class level with static.