Python karışımları anti-patern midir?


34

Bunun pylintve diğer statik analiz araçlarının her şeyi bilmediğini ve bazen onların tavsiyelerine uyulmaması gerektiğinin farkındayım. (Bu sadece conventions için değil, çeşitli mesaj sınıfları için geçerlidir .)


Eğer sınıflarım varsa

class related_methods():

    def a_method(self):
        self.stack.function(self.my_var)

class more_methods():

    def b_method(self):
        self.otherfunc()

class implement_methods(related_methods, more_methods):

    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):
        self.a_method()

Açıkçası, bu karar verildi. İsterseniz, daha iyi bir örnek .

Bu stile "mixins" kullanılarak çağrıldığına inanıyorum.

Diğer araçlar gibi, pylintoranlar bu kod -21.67 / 10, öncelikle düşündüğü için more_methodsve related_methodsyok selfveya nitelikleri otherfunc, stack, annd my_varkodu çalıştırmadan, bu görünüşte göremiyorum çünkü related_methodsve more_methodskarma-in vardır implement_methods.

Derleyiciler ve statik analiz araçları Halting Sorunu'nu her zaman çözemezler , ancak bunun kesinlikle kalıtsal olanlara bakmanın implement_methodsbunun mükemmel bir şekilde geçerli olduğunu göstereceğini ve bunun yapılması çok kolay bir şey olduğunu gösterdiği bir durum olduğunu düşünüyorum.

Statik analiz araçları neden bu geçerli (bence) OOP modelini reddediyor?

Ya:

  1. Mirası kontrol etmeye bile çalışmıyorlar ya da

  2. karışımlar deyimsel, okunabilir Python ile cesareti kırılmıştır


1. soruyorum çünkü eğer belli ki yanlıştır pylintbenim bir sınıf hakkında o devralır söyle unittest.TestCasekullandığı o self.assertEqual, (bir şey sadece tanımlanan unittest.TestCase), bu yok değil şikayetçi.

Karışımlar pitonik mi yoksa cesaretsiz mi?


1
Bu kötü bir soru mu? Konu dışı mı? cevaplanamaz mı? Ben aptal mıyım? İnsanlar DV yapabilir ancak iyileştirmelerine yardımcı olmak istemiyorlar.
kedi

1
İnsanların "bu bir (anti-) kalıp mı" veya "bu (un) pitonik mi" diye sormaktan bıkması muhtemel olan birileri var.

9
@MichaelT Bu iyi. O zaman soruları gözden geçirmeyi bırakabilirler.
Katana314

2
@tac insanlar çeşitli nedenlerden dolayı indirgeyeceklerdir, ancak nedenini söylemeleri gerekmeyecekler; kabul edilebilir cevap 8 yukarı ve 1 aşağı, özellikle indirimlerin ücretsiz olduğu bir soruda oldukça iyidir. Seni üzmesine izin verme. Şerefe.
Aaron Hall

@AaronHall İnsanların oylarıyla istediklerini yapmalarına izin verildiğinin farkındayım, aslında aynı şeyi şikayet eden yeni kullanıcılara söylüyorum.
kedi,

Yanıtlar:


16

Karıştırıcılar sadece araç tarafından kabul edilen bir kullanım durumu değildir. Bu, mutlaka kötü bir kullanım durumu anlamına gelmez, python için nadir bir durumdur.

Karışımların belirli bir durumda uygun şekilde kullanılıp kullanılmadığı başka bir konudur. En sık gördüğüm mixin anti-pattern, sadece bir kombinasyonun karıştırılması istendiğinde, karışımları kullanıyor. Bu sadece bir tanrı sınıfını saklamanın dolambaçlı bir yoludur. Eğer bir sebep düşünemiyorum yapamıyorsanız hemen dışarı takas veya Mixins birini terk etmek, bir mixin olmamalıdır.


evet, bu bir tanrı nesnesi, itiraf ediyorum. Bu durumda CPU'nun bir tanrı nesnesi olması sorun değil.
kedi

15

Mixins'in kesinlikle Pythonic olabileceğine inanıyorum. Bununla birlikte, linter'inizi susturmanın - ve Mixin'lerin okunabilirliğini arttırmanın idiomatik yolu, (1) her ikisinin de (1) bir Mixin'in çocuklarının uygulaması gereken yöntemleri açıkça tanımlayan soyut yöntemleri tanımlamak ve (2) önceden tanımlamaktır. NoneÇocukların başlatması gereken Mixin veri üyeleri için değerli alanlar.

Örneğinize bu kalıbı uygulamak:

from abc import ABC, abstractmethod


class related_methods():
    my_var = None
    stack = None

    def a_method(self):
        self.stack.function(self.my_var)


class more_methods(ABC):
    @abstractmethod
    def otherfunc(self):
        pass

    def b_method(self):
        self.otherfunc()


class implement_methods(related_methods, more_methods):
    def __init__(self):
        self.stack  = some()
        self.my_var = other()

    def otherfunc(self):
        self.a_method()

2
Cevabınız için +1, abstract other(self): passşey linter'in benim için kafa karışıklığını değiştirmesine rağmen
kedi

@Abstractmethod ;-) olmadan daha da kafa karıştırıcı ;-) İlk önce Java ile başladım, bu yüzden bu benim için iyi.
Chris Huang-Leaver

9

Bence Katmalar iyi olabilir, ama aynı zamanda PyLint sağ bu durumda olduğunu düşünüyorum. Feragatname: görüş temelli şeyler izler.

İyi bir sınıf, karışımlar dahil, açık bir sorumluluğa sahiptir. İdeal olarak, bir karışımın erişeceği tüm durumu ve ele alması gereken mantığı taşıması gerekir. Örneğin, iyi bir karışım last_updatedbir ORM model sınıfına bir alan ekleyebilir , onu ayarlamak için mantık sağlayabilir ve en eski / en yeni kaydı aramanın yöntemlerini sağlayabilir.

Bildirilmemiş örnek üyelere (değişkenler ve yöntemler) atıfta bulunmak biraz garip görünüyor.

Doğru yaklaşım, eldeki göreve çok bağlıdır.

İçinde tutulan ilgili durum biti ile bir karışım olabilir.

Halen bir mixin aracılığıyla dağıttığınız yöntemlerin bir temel sınıfta olduğu, düşük seviye uygulama farklarının alt sınıflara ait olduğu farklı bir sınıf hiyerarşisi olabilir. Bu yığın işlemleri ile durumunuza en uygun görünüyor.

Bir veya iki yöntem ekleyen bir sınıf dekoratör olabilir; Bu, genellikle yöntem oluşturmayı etkilemek için dekoratöre bazı argümanlar iletmeniz gerektiğinde anlamlıdır.

Sorununuzu belirtin, daha büyük tasarımla ilgili endişelerinizi açıklayın, sonra davanızda bir şeylerin bir kalıp karşıtı olup olmadığını tartışabiliriz.


6

Linter, bir sınıfı bir karışım olarak kullandığınızı bilmiyor. Pylint, sınıf adının sonuna 'mixin' veya 'Mixin' son ekini eklerseniz bir mixin kullandığının farkındadır, ardından linter şikayet etmeyi durdurur.

linter_without_mixins linter2_with_mixin

Karışımlar kötü değil ya da başlı başına iyi, sadece bir araçtır. Onları iyi bir kullanım veya kötü bir kullanım haline getirirsiniz.


2
Bu bir yorum gibi daha fazla okur, Nasıl
gnat

2
bu değerli bir cevap çünkü başka bir ipucunu asla bilemeyeceğimi sanmıyorum
kedi

1

Karışımlar iyi mi?

Python karışımları anti-patern midir?

Karışımlar cesareti kırılmaz - çoklu kalıtım için iyi bir kullanım durumudur.

Linter'in neden şikayet ediyor?

PyLint nerede bilmediği için açıkçası şikayet ediyor otherfunc, stackve my_var geliyor.

Önemsiz?

Bu iki yöntemi, söz konusu örnekte veya burada gösterilen daha önemsiz bağlantılı örneğinizde, ayrı üst sınıflara ayırmanız için hemen iyi bir neden yoktur.

201
202 class OpCore():
203     # nothing runs without these
204
205 class OpLogik(): 
206     # logic methods... 
207 
208 class OpString(): 
209     # string things
210 
211 
212 class Stack(OpCore, OpLogik, OpString): 
213 
214     "the mixin mixer of the above mixins" 

Mixins ve gürültü maliyetleri

Yaptıklarınızın maliyeti linter raporunuzu gürültü yapmaktır. Bu ses kodunuzla daha önemli problemleri gizleyebilir. Bu tartmak için önemli bir maliyettir. Diğer bir maliyet, programcıların anlamını keşfetmesini zorlaştırabilen ilişkili kodunuzu farklı ad alanlarına ayırmanızdır.

Sonuç

Kalıtım kodun yeniden kullanılmasına izin verir. Kodlarınızı yeniden kullanmak için tekrar kod alırsanız, harika, muhtemelen sizin için muhtemel diğer masraflardan ağır basan bir değer yarattılar. Kod satırını tekrar kullanıyorsanız / kod satırlarını almıyorsanız, muhtemelen karışımlarınız için fazla bir değer elde edemezsiniz ve bu noktada, gürültünün maliyetinin faydalardan daha büyük olduğunu düşünüyorum.


Onları birbiriyle bağlantılı, önemsiz bir örnekte ayırmak için iyi bir neden var - matematiği uygulayan, dize uygulayan bir diğeri, vb. ileri çorba almak için.
kedi,

“Başka bir maliyet, kodunuzu programcıların anlamını keşfetmelerini zorlaştırabilecek farklı ad alanlarına ayırmanızdır” - hayır, bu böyle değil. Sınıf ad alanları, bir grup metodun ne yaptığını söylemeyi kolaylaştırır ve birisi yığını kullanmak istediğinde, bireysel malzemeleri değil, Çorba Çorbası'nı çağırmalı / uygulamalıdır
cat

@ cat muhtemelen gerçek bir büyük projede kullanılmadıklarından ve kullanılmadıklarından, hiçbir örnek karışım kullanma noktanızı desteklemez. Her ikisi de karışımın yalnızca bir kez kullanıldığını gösterir; bu durumda, uygulamayı sadece bir yere koymak daha iyi stil ve organizasyondur. Şimdi, sınıflar arasında ortak özellikler kullanmak istediğiniz, ancak ortak bir temel sınıf istemiyorsanız, bir karışımını kullanacağınız bir durum gösterebilirseniz. Astar sorunuzun yanında olan (UltraBird buna iyi cevap verdi). Ancak bu, genel olarak miks uygulanabilirliğine ilişkin sorunuza cevap verir.
dlamblin
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.