Pylint'i bazı kodlarda çalıştırıyorum ve "Çok az genel yöntem (0/2)" hatası alıyorum. Bu mesajın anlamı nedir? PyLint dokümanlar yararlı değildir:
Sınıfın çok az genel yöntemi olduğunda kullanılır, bu yüzden gerçekten değdiğinden emin olun.
Pylint'i bazı kodlarda çalıştırıyorum ve "Çok az genel yöntem (0/2)" hatası alıyorum. Bu mesajın anlamı nedir? PyLint dokümanlar yararlı değildir:
Sınıfın çok az genel yöntemi olduğunda kullanılır, bu yüzden gerçekten değdiğinden emin olun.
Yanıtlar:
Hata temelde sınıfları anlamına gelmediğini söylüyor sadece temelde bir sözlük olarak sınıf davrandığınız gibi veri depolamak. Sınıflar, tuttukları veriler üzerinde işlem yapmak için en az birkaç yönteme sahip olmalıdır.
Sınıfınız böyle görünüyorsa:
class MyClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
namedtuple
Bunun yerine bir sözlük veya a kullanmayı düşünün . Bir sınıf en iyi seçenek gibi görünse de, onu kullanın. pylint her zaman neyin en iyi olduğunu bilmez.
Bunun namedtuple
değişmez olduğunu ve somutlaştırmada atanan değerlerin daha sonra değiştirilemeyeceğini unutmayın.
dict
veya kullanın namedtuple
. Nesnenize biraz mantık eklemek istediğinizde bir sınıf kullanın (örneğin, bir şeylerin oluşturulduğunda olmasını istiyorsanız, eklendiğinde bazı özel şeylere ihtiyacınız var, üzerinde bazı işlemler gerçekleştirmek, nasıl olduğunu kontrol etmek istiyorsunuz. görüntüleniyor, vb.)
namedtuple
berbat - çirkin sözdizimine sahip olmanın yanı sıra, onu belgeleyemez veya varsayılan değerleri kolayca sağlayamazsınız.
namedtuple
karardan pişman oldum. Hem adlandırılmış erişime hem de dizine alınmış erişim özniteliklerine izin vermek tutarsızdır.
Bir sınıfı genişletiyorsanız, önerim bu uyarıyı sistematik olarak devre dışı bırakmak ve devam etmek, örneğin Kereviz görevleri durumunda:
class MyTask(celery.Task): # pylint: disable=too-few-public-methods
"""base for My Celery tasks with common behaviors; extends celery.Task
...
Yalnızca tek bir işlevi genişletiyor olsanız bile, bu tekniğin işlevini yerine getirmek için kesinlikle bir sınıfa ihtiyacınız var ve genişletme kesinlikle üçüncü taraf sınıfları hacklemekten daha iyidir!
min-public-methods=0
içinde [BASIC]
yapılandırma dosyasının bölümüne. Bu, onu bulduğum tüm disable=
öğelerinizden (içinde [MESSAGE CONTROL]
) ayrı bir satıra koymanıza izin verir , yapılandırma değişikliği ile birlikte şeyleri neden etkinleştirdiğiniz ve devre dışı bıraktığınız hakkında ayrıntılı yorumlar eklemeyi kolaylaştırır.
Bu, başka bir pylint
kör kural durumudur .
"Sınıflar veri depolamaya yönelik değildir" - bu yanlış bir ifadedir. Sözlükler her şey için iyi değildir. Bir sınıfın veri üyesi anlamlı, sözlük öğesi ise isteğe bağlı bir şeydir. Kanıt: a'yı dictionary.get('key', DEFAULT_VALUE)
önlemek için yapabilirsiniz KeyError
, ancak __getattr__
varsayılan ile basit bir şey yoktur .
Cevabımı güncellemem gerekiyor. Şu anda - a'ya ihtiyacınız struct
varsa, iki harika seçeneğiniz var:
attrs
Bunlar bunun için bir kitaplık:
https://www.attrs.org/en/stable/
import attr
@attr.s
class MyClass(object): # or just MyClass: for Python 3
foo = attr.ib()
bar = attr.ib()
Fazladan ne elde edersiniz: kurucular, varsayılan değerler, doğrulama __repr__
, salt okunur nesneler ( namedtuples
Python 2'de bile değiştirmek için ) ve daha fazlasını yazmamak.
dataclasses
(Py 3.7+)Hwjp'nin yorumundan sonra şunu da tavsiye ederim dataclasses
:
https://docs.python.org/3/library/dataclasses.html
Bu neredeyse en az onun kadar iyidir attrs
ve Python 3.7+ dışında ekstra bağımlılık içermeyen standart bir kitaplık mekanizmasıdır ("piller dahil").
NamedTuple
harika değil - özellikle python 3'lerden önce typing.NamedTuple
:
https://docs.python.org/3/library/typing.html#typing.NamedTuple
- "türetilmiş sınıf NamedTuple
" kalıbına kesinlikle göz atmalısınız . Python 2 - namedtuples
dize açıklamalarından oluşturulmuş - çirkin, kötü ve "dizge değişmezleri içinde programlama" aptalca.
Şu anki iki yanıta katılıyorum ("başka bir şey kullanmayı düşünün, ancak pylint her zaman doğru değildir" - kabul edilen yanıt ve "pylint bastırıcı yorum kullan"), ancak kendi önerim var.
Bunu bir kez daha belirtmeme izin verin: Bazı sınıflar sadece verileri depolamaya yöneliktir .
Şimdi de dikkate alma seçeneği - property
-ies kullanın .
class MyClass(object):
def __init__(self, foo, bar):
self._foo = foo
self._bar = bar
@property
def foo(self):
return self._foo
@property
def bar(self):
return self._bar
Yukarıda, Değer Nesnesi için uygun olan salt okunur özelliklere sahipsiniz (örneğin, Etki Alanına Dayalı Tasarımdakiler gibi), ancak ayarlayıcılar da sağlayabilirsiniz - bu şekilde sınıfınız sahip olduğunuz alanların sorumluluğunu üstlenebilir - örneğin bazı doğrulama yapmak vb. için (ayarlayıcılarınız varsa, bunları kurucuda kullanarak atayabilirsiniz, yani self.foo = foo
doğrudan self._foo = foo
, ancak dikkatli olmak yerine , ayarlayıcılar diğer alanların zaten başlatılmış olduğunu varsayabilir ve sonra yapıcıda özel doğrulamaya ihtiyacınız vardır) .
attrs
, aslında dataclasses
modül oluşturmanın planı olan kitaplığı kullanabilirsiniz .
namedtuples
kalıtım için garip bir sözdizimi var ... birini kullanan her sınıfın bunun adlandırılmış bir demet olduğunu bilmesini ve __new__
bunun yerine kullanmasını gerektirir __init__
. dataclasses
bu sınırlamaya sahip değilsiniz
Patronunuzun tek sorumluluk ilkesini beklemesi zordur, ancak pylint hayır diyor. Bu yüzden sınıfınıza ikinci bir yöntem ekleyin, böylece sınıfınız tek sorumluluk ilkesini ihlal eder. Tek sorumluluğu ne kadar ileri götürmeniz gerektiği ilkesi, bakanın gözündedir.
Düzeltmem
Sınıfıma fazladan bir yöntem ekledim, bu yüzden şimdi 2 şey yapıyor.
def __str__(self):
return self.__class__.__name__
Şimdi sınıfımı 2 ayrı dosyaya bölmem gerekip gerekmediğini merak ediyorum ve belki modüller de olabilir.
sorun çözüldü, ancak bütün gününü yaşam ve ölüm gibi onunla uğraşmak yerine şartnameyi tartışarak geçiren meslektaşlarımla değil.