Kelas Python hanya dengan satu instance: Kapan membuat instance kelas (tunggal) dan kapan harus bekerja dengan kelas?

11

Diberikan kelas Python yang akan dipakai hanya sekali, yaitu hanya akan ada satu objek dari kelas. Saya bertanya-tanya dalam kasus apa masuk akal untuk membuat instance kelas tunggal alih-alih bekerja langsung dengan kelas.

Ada pertanyaan serupa , tetapi memiliki fokus berbeda:

  1. ini tentang pengelompokan variabel dan fungsi global ke dalam kelas dan
  2. Itu bukan Python-spesifik. Yang terakhir berarti tidak mempertimbangkan fakta bahwa (dalam Python) kelas adalah objek juga.

MEMPERBARUI:

Dengan Python, saya bisa melakukan hal berikut dengan kelas dan objek:

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

Jadi saya tidak melihat bagaimana pilihan antara kelas dan turunan dari kelas itu adalah tentang keadaan (dengan Python). Saya bisa mempertahankan keadaan dengan salah satu dari keduanya.

Selain itu, motivasi untuk membuat kelas saya / kelas bukan tentang menegakkan persyaratan Singleton.

Juga, ini bukan soal membuat Tipe baru.

Motivasinya adalah untuk mengelompokkan kode dan data terkait dan memiliki antarmuka untuk itu. Inilah sebabnya saya awalnya memodelkannya sebagai kelas dalam diagram kelas. Hanya ketika sampai pada implementasi saya mulai bertanya-tanya apakah akan membuat kelas ini atau tidak.

langlauf.io
sumber

Jawaban:

16

Diberikan kelas Python yang akan dipakai hanya sekali, yaitu hanya akan ada satu objek dari kelas. Saya bertanya-tanya dalam kasus apa masuk akal untuk membuat instance kelas tunggal alih-alih bekerja langsung dengan kelas.

Jadi begini:

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

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

versus ini?

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

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

Rekomendasi

Saya pasti akan lebih memilih yang dimaksudkan untuk dipakai. Ketika Anda membuat "tipe hal" yang menyiratkan bahwa Anda membuat hal-hal jenis itu.

Motivasinya adalah untuk mengelompokkan kode dan data terkait dan memiliki antarmuka untuk itu.

Yang mengatakan, mengapa tidak hanya menggunakan modul karena semua yang Anda inginkan adalah namespace? Modul adalah lajang, kode dan data terkait kelompok, dan ini sedikit lebih sederhana dan mungkin akan dianggap lebih Pythonic:

var1 ='foo'

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

Jadi penggunaannya bukan:

from modules.singleton import Singleton
Singleton.foobar()

atau

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

melakukan hal ini:

from modules import singleton
singleton.foobar()
Aaron Hall
sumber
3
Terima kasih atas jawaban anda. Apakah Anda benar-benar menyarankan membuat modul baru (file .py baru) untuk setiap fungsi (termasuk variabel)? Ini dapat menghasilkan banyak file .py kecil. Atau akankah Anda mengelompokkan semua fungsi dan variabel "sekurang-kurangnya terkait)" kelas-kurang "dalam satu modul?
langlauf.io
Satu komentar lagi: Anda menulis "karena yang Anda inginkan adalah namespace". Yang saya inginkan adalah mengelompokkan kode terkait, yaitu fungsi dan data, di satu tempat, dan memiliki antarmuka untuk itu. Ini bukan tentang membuat "Jenis". Selama desain, ini akan menghasilkan kelas dalam diagram kelas, bukan?
langlauf.io
2

Saya bertanya-tanya dalam kasus apa masuk akal untuk membuat instance kelas tunggal alih-alih bekerja langsung dengan kelas.

Ini adalah salah satu hal yang akan menyebabkan perang agama jika Anda terlalu banyak terlibat.

Tetapi secara umum praktik yang telah saya lihat berkali-kali adalah bahwa metode kelas harus memusatkan perhatian pada diri mereka sendiri hanya dengan membuat instance kelas itu.

Jika Anda berpikir tentang apa kelas itu, apa tujuan / perilakunya, maka ini masuk akal. Tujuan kelas adalah untuk membuat instance objek yang didasarkan pada dirinya sendiri . Ini adalah cetak biru yang juga dapat membangun gedung. Kelas "Pengguna" membuat objek "pengguna". Kelas "Anjing" membuat objek "anjing" dll

Berikan ini adalah perilaku sebuah kelas masuk akal maka metode yang Anda tambahkan ke kelas "X" akan memusatkan perhatian mereka dengan membuat objek "x".

Jadi, bahkan jika Anda hanya akan membutuhkan satu objek "x" Anda harus tetap instanciate itu.

Menambahkan metode ke kelas X yang tidak terkait dengan membuat instance objek "x" dapat menyebabkan membingungkan kode yang tidak diharapkan. Tentu saja ada banyak contoh di dunia nyata di mana orang telah melakukan ini, tetapi seperti saya katakan bahwa jalan menuju perang agama.

Cormac Mulhall
sumber