Yalnızca bir örneği olan Python sınıfları: Ne zaman (tek) sınıf örneği oluşturulur ve bunun yerine sınıfla ne zaman çalışır?


11

Yalnızca bir kez başlatılacak olan bir Python sınıfı verildiğinde, yani sınıfın yalnızca bir nesnesi olacaktır. Hangi durumlarda doğrudan sınıfla çalışmak yerine tek bir sınıf örneği oluşturmanın mantıklı olduğunu merak ediyordum.

Benzer bir soru var , ama farklı bir odağı var:

  1. küresel değişkenleri ve fonksiyonları bir sınıfa ayırmak ve
  2. Python'a özgü değil. İkincisi, (Python'da) sınıfların da nesne olduğu gerçeğini dikkate almadığı anlamına gelir.

GÜNCELLEME:

Python'da, hem sınıflar hem de nesnelerle aşağıdakileri yapabilirim:

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

Yani bir sınıf ve o sınıfın bir örneği arasındaki seçim devlet (Python) hakkında nasıl görmüyorum. İkisinden biriyle durumu koruyabilirim.

Ayrıca, sınıf / sınıf örneğimi oluşturma motivasyonu bir Singleton gereksinimini uygulamakla ilgili değildir.

Ayrıca, yeni bir Tip oluşturmakla da ilgili değil.

Motivasyon, ilgili kod ve verileri gruplandırmak ve onunla bir arayüze sahip olmaktır. Bu yüzden başlangıçta bir sınıf diyagramında bir sınıf olarak modellenmiştim. Sadece uygulama söz konusu olduğunda bu sınıfı somutlaştırıp açmayacağımı merak etmeye başladım.

Yanıtlar:


16

Yalnızca bir kez başlatılacak olan bir Python sınıfı verildiğinde, yani sınıfın yalnızca bir nesnesi olacaktır. Hangi durumlarda doğrudan sınıfla çalışmak yerine tek bir sınıf örneği oluşturmanın mantıklı olduğunu merak ediyordum.

Yani bu:

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

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

buna karşı mı?

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

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

Öneri

Kesinlikle somutlaştırılacak olanı tercih ederim. Bir "şey türü" oluşturduğunuzda, o tür şeyleri oluşturduğunuz anlamına gelir.

Motivasyon, ilgili kod ve verileri gruplandırmak ve onunla bir arayüze sahip olmaktır.

Bununla birlikte, istediğiniz tek şey bir ad alanı olduğundan neden sadece bir modül kullanmıyorsunuz? Modüller tek tonlu, grupla ilgili kod ve verilerdir ve bu biraz daha basittir ve muhtemelen daha Pythonic olarak kabul edilir:

var1 ='foo'

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

Yani kullanım yerine:

from modules.singleton import Singleton
Singleton.foobar()

veya

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

Bunu yap:

from modules import singleton
singleton.foobar()

3
Cevabınız için teşekkürler. Her işlev için (değişkenler dahil) yeni bir modül (yeni bir .py dosyası) oluşturmayı gerçekten önerir misiniz? Bu, birçok küçük .py dosyasına neden olabilir. Yoksa "sınıfsız" işlevlerin ve değişkenlerin tümünü (en azından bir şekilde ilişkili) tek bir modülde gruplayabilir misiniz?
langlauf.io

Bir açıklama daha: "İstediğiniz tek şey bir ad alanı olduğundan" yazarsınız. Ne istediğim tek bir yerde ilgili kod, yani fonksiyonlar ve veri gruplamak ve bir arayüz var. Bu bir "Tür" oluşturmakla ilgili değildir. Tasarım sırasında, bu yine de bir sınıf diyagramında bir sınıfa neden olur, değil mi?
langlauf.io

2

Hangi durumlarda doğrudan sınıfla çalışmak yerine tek bir sınıf örneği oluşturmanın mantıklı olduğunu merak ediyordum.

Bu, çok fazla girerseniz dini bir savaşa neden olacak şeylerden biridir.

Ancak genel olarak birçok kez gördüğüm bir uygulama, sınıf yöntemlerinin kendilerini yalnızca o sınıfın örneklerini oluşturmakla ilgilendirmesi gerektiğidir.

Bir sınıfın ne olduğunu, amacının / davranışının ne olduğunu düşünüyorsanız, bu mantıklıdır. Bir sınıfın amacı, kendisine dayalı nesnelerin örneklerini oluşturmaktır . Binayı da inşa edebilen bir plan. "Kullanıcı" sınıfı "kullanıcı" nesneleri oluşturur. Bir "Köpek" sınıfı "köpek" nesneleri vb.

Bu, bir sınıfın davranışını verirse, "X" sınıfına eklediğiniz yöntemlerin "x" nesneleri oluşturmakla kendilerini ilgilendireceği mantıklıdır.

Bu nedenle, yalnızca bir "x" nesnesine ihtiyacınız olsa bile, onu hemen örneklemeniz gerekir.

X sınıfına "x" nesnesi örnekleri oluşturmakla ilgili olmayan yöntemler eklemek, beklenmedik kodların karıştırılmasına neden olabilir. Elbette gerçek dünyada insanların bunu zaten yaptıkları tonlarca örnek var, ama dediğim gibi bu yol dini savaşa yol açıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.