Các lớp Python chỉ có một thể hiện: Khi nào tạo một cá thể lớp (đơn) và khi nào làm việc với lớp thay thế?


11

Cho một lớp Python sẽ được khởi tạo chỉ một lần, tức là sẽ chỉ có một đối tượng của lớp. Tôi đã tự hỏi trong trường hợp nào có ý nghĩa để tạo một cá thể lớp duy nhất thay vì làm việc trực tiếp với lớp thay thế.

Có một câu hỏi tương tự , nhưng nó có một trọng tâm khác:

  1. đó là về việc nhóm các biến và hàm toàn cầu vào một lớp và
  2. Nó không phải là Python cụ thể. Cái sau có nghĩa là nó không xem xét thực tế rằng các lớp (trong Python) cũng là các đối tượng.

CẬP NHẬT:

Trong Python, tôi có thể làm như sau với cả lớp và đối tượng:

class A(object):
    pass

A.some_state_var = True
# Then later
A.some_state_var = False


my_a = A()

my_a.some_state_var = True
# Then later
my_a.some_state_var = False

Vì vậy, tôi không thấy sự lựa chọn giữa một lớp và một thể hiện của lớp đó là về trạng thái (bằng Python). Tôi có thể duy trì trạng thái với một trong hai.

Hơn nữa, động lực để tạo ra cá thể lớp / lớp của tôi không phải là về việc thực thi một yêu cầu Singleton.

Ngoài ra, nó không phải là quá nhiều về việc tạo ra một Loại mới.

Động lực là để nhóm mã và dữ liệu liên quan và có một giao diện với nó. Đây là lý do tại sao ban đầu tôi mô hình hóa nó như là một lớp trong sơ đồ lớp. Chỉ khi bắt đầu thực hiện, tôi mới bắt đầu tự hỏi có nên khởi tạo lớp này hay không.

Câu trả lời:


16

Cho một lớp Python sẽ được khởi tạo chỉ một lần, tức là sẽ chỉ có một đối tượng của lớp. Tôi đã tự hỏi trong trường hợp nào có ý nghĩa để tạo một cá thể lớp duy nhất thay vì làm việc trực tiếp với lớp thay thế.

Vì vậy, đây là:

class Singleton:
    '''don't bother instantiating me'''
    clsvar1 = 'foo'

    @classmethod
    def foobar(cls, *args, **kwargs):
        if condition():
            cls.clsvar1 = 'bar'

so với điều này?

class Singleton:
    '''instantiate and use me'''
    def __init__(self):
        self.var1 = 'foo'

    def foobar(self, *args, **kwargs):
        if condition():
            self.var1 = 'bar'

sự giới thiệu

Tôi chắc chắn sẽ thích cái mà dự định sẽ được khởi tạo. Khi bạn tạo một "loại sự vật" ngụ ý rằng bạn tạo ra những thứ thuộc loại đó.

Động lực là để nhóm mã và dữ liệu liên quan và có một giao diện với nó.

Điều đó nói rằng, tại sao không chỉ sử dụng một mô-đun vì tất cả những gì bạn muốn là một không gian tên? Các mô-đun là singletons, mã và dữ liệu liên quan đến nhóm, và điều này đơn giản hơn một chút và có lẽ sẽ được coi là Pythonic hơn:

var1 ='foo'

def foobar(*args, **kwargs):
    global var1
    if condition():
        var1 = 'bar'

Vì vậy, việc sử dụng sẽ thay vì:

from modules.singleton import Singleton
Singleton.foobar()

hoặc là

from modules.singleton import Singleton
the_singleton = Singleton()
the_singleton.foobar()

làm cái này:

from modules import singleton
singleton.foobar()

3
Cảm ơn câu trả lời của bạn. Bạn có thực sự đề nghị tạo một mô-đun mới (một tệp .py mới) cho mọi chức năng (bao gồm các biến) không? Điều này có thể dẫn đến nhiều tệp .py nhỏ. Hoặc bạn sẽ nhóm tất cả (ít nhất là bằng cách nào đó liên quan) các hàm và biến "không có lớp" trong một mô-đun?
langlauf.io

Thêm một nhận xét: Bạn viết "vì tất cả những gì bạn muốn là một không gian tên". Những gì tôi muốn là nhóm mã liên quan, tức là các chức năng và dữ liệu, ở một nơi và có một giao diện với nó. Nó không phải là quá nhiều về việc tạo ra một "Loại". Trong quá trình thiết kế, điều này sẽ dẫn đến một lớp trong sơ đồ lớp, phải không?
langlauf.io

2

Tôi đã tự hỏi trong trường hợp nào có ý nghĩa để tạo một cá thể lớp duy nhất thay vì làm việc trực tiếp với lớp thay thế.

Đây là một trong những điều sẽ gây ra một cuộc chiến tôn giáo nếu bạn tham gia vào nó nhiều.

Nhưng nói chung, một thực tế mà tôi đã thấy nhiều lần là các phương thức lớp chỉ nên quan tâm đến việc tạo các thể hiện của lớp đó.

Nếu bạn nghĩ về một lớp học là gì, mục đích / hành vi của nó là gì, thì điều này có ý nghĩa. Mục đích của một lớp là tạo ra các thể hiện của các đối tượng dựa trên chính nó . Đó là một kế hoạch chi tiết cũng có thể xây dựng tòa nhà. Một lớp "Người dùng" tạo các đối tượng "người dùng". Một lớp "Dog" tạo ra các đối tượng "dog", v.v.

Cho rằng đây là hành vi của một lớp, có nghĩa là các phương thức bạn thêm vào lớp "X" sẽ liên quan đến việc tạo các đối tượng "x".

Vì vậy, ngay cả khi bạn chỉ cần một đối tượng "x", bạn vẫn nên kích hoạt nó.

Việc thêm các phương thức vào lớp X không liên quan đến việc tạo các thể hiện của các đối tượng "x" có thể dẫn đến việc nhầm lẫn mã không mong muốn. Tất nhiên có rất nhiều ví dụ trong thế giới thực, nơi mọi người đã làm điều này bằng mọi cách, nhưng như tôi đã nói rằng con đường dẫn đến chiến tranh tôn giáo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.