Bir Python sınıfında yöntem sipariş etmenin iyi bir yolu nedir?


89

Bir Python sınıfında yöntem sipariş etmek istiyorum ama doğru sıranın ne olduğunu bilmiyorum.

Eclipse'de PyDev ile yöntemler çıkardığımda, Eclipse ayıklanan yöntemi değiştirilen yöntemin üstüne koyuyor. Ancak bu, alt düzeydeki ayrıntıları daha yüksek düzeydeki ayrıntıların önüne koyar. Bob Amca'ya göre, kodumun bir gazetenin manşetleri gibi okunması için tam tersini yapmalıyım. Java'yı programladığımda onun tavsiyesine uyuyorum.

Python için en iyi uygulama nedir?


8
Bir en iyi uygulama yok. En mantıklı olanı yapın - tepeye yakın önemli şeyler iyi bir fikirdir ve tutarlılık genellikle iyi bir şeydir. PEP-8 bundan bahsetmiyor ve eğer taşa yerleştirilecek olsaydı, orası olurdu.
Gareth Latty

4
Ve PEP8 bile her zaman değiştirilemez.
Ignacio Vazquez-Abrams

1
Bunu genellikle işlevsellik konusunda grup halinde yapıyorum (alma, ayarlama, vb.)
CppLearner

Yöntem işlevlerinin sırasının keyfi olabileceğini unutmamak önemlidir, çünkü bir sınıf bildirimi yalnızca yöntem işlevlerini tanımlar , onları çağırmaz . Bu, sınıf yöntemi yordamlarının kaynak kodunun, daha sonra listede aşağıda tanımlanacak yöntem işlevlerini başarıyla kullanmasını sağlar.
DragonLord

Yanıtlar:


67

Başkalarının da belirttiği gibi, yöntemlerinizi sipariş etmenin doğru bir yolu yoktur. Belki bir PEP önerisi yararlı olabilir, ama yine de. Sorunuza olabildiğince tarafsız bir şekilde yaklaşmaya çalışmama izin verin.

  • Önce arayüzler: Genel yöntemler ve Python sihirli fonksiyonları, sınıfın arayüzünü tanımlar. Çoğu zaman, siz ve diğer geliştiriciler bir sınıfı değiştirmek yerine kullanmak istersiniz. Böylece o sınıfın arayüzüyle ilgilenecekler. Bunu kaynak kodda ilk sıraya koymak, umursamadığınız uygulama ayrıntılarında gezinmeyi önler.

  • Özellikler, sihirli yöntemler , genel yöntemler: Hepsi sınıfın arayüzünün bir parçası olan bu üçü arasındaki en iyi sırayı tanımlamak zordur. @EthanFurman'ın dediği gibi, tüm proje için tek bir sisteme bağlı kalmak çok önemlidir. Genel olarak, insanlar __init__()sınıftaki en iyi ilk işlevi bekler , bu yüzden hemen aşağıdaki diğer sihirli yöntemleri takip ederim.

  • Okuma sırası: Temel olarak bir hikaye anlatmanın iki yolu vardır: Aşağıdan yukarıya veya yukarıdan aşağıya. Bir geliştirici, üst düzey işlevleri ilk sıraya koyarak, ilk birkaç satırı okuyarak sınıfı kabaca anlayabilir. Aksi takdirde, sınıfı anlamak için tüm dersi okumak gerekir ve çoğu geliştiricinin buna vakti olmaz. Genel bir kural olarak, kendi vücutlarından çağrılan tüm yöntemlerin üzerine yöntemler koyun.

  • Sınıf yöntemleri ve statik yöntemler: Genellikle bu, yukarıda açıklanan okuma sırası ile ifade edilir. Normal yöntemler tüm yöntemleri çağırabilir ve bu nedenle önce gelir. Sınıf yöntemleri yalnızca sınıf yöntemlerini ve statik yöntemleri çağırabilir ve sonra gelir. Statik yöntemler, sınıfın diğer yöntemlerini çağırıp sonuncu olamaz.

Bu yardımcı olur umarım. Bu kuralların çoğu bu arada Python'a özgü değildir. Yöntem düzenini uygulayan bir dil bilmiyorum ama öyleyse oldukça ilginç olur ve lütfen yorum yapın.


1
Genellikle bir dil, siparişi zorlamaz. Ancak bazı dillerin ortak kuralları vardır. Örneğin, C # StyleCop'un katı bir sıralama kuralları vardır. Java için stackoverflow.com/questions/4668218 , vb.
Sayfasına

1
sınıf yöntemleri: bunlar genellikle kurucular olarak kullanılır ve daha sonra genellikle __init__açıkça (birlikte __new__) veya örtük olarak (varsayılan kurucu aracılığıyla) çağırırlar, bu nedenle bunları birlikte yerleştirmek için bir neden olur __init__. (Ben hiç görmedim rağmen yerleştirilmesini önce __init__ .)
oulenz

15

Doğru bir düzen yok. Bir sistem seçin ve ona bağlı kalın. Kullandığım şu:

class SomeClass(object):
    def __magic_methods__(self):
        "magic methods first, usually in alphabetical order"
    def _private_method(self):
        "worker methods next, also in alpha order"
    def a_method(self):
        "then normal methods, also in alpha order"

2
Statik yöntemler, sınıf değişkenleri ve @ özellik dekore edilmiş yöntemler için tercihiniz nedir?
John Mee

@JohnMee: Her şeyden önce koyduğum sınıf değişkenleri; Benim katlama yöntemi derileri @staticmethod, @classmethod, @propertyve diğer @decoratorsatırlar Ben (özellikler arasında gidip eğilimi haricinde nereye gittiğini belirlemek için yöntemi türünü kullanmak bu yüzden _private_methodsve normal_methods).
Ethan Furman

Öyleyse, sıralama temelde çok özel "sihirli" yöntemlerden özele ve normal yöntemlere giderse, bu @classmethods sonraki ( @classmethod def a_class_method(cls)) sonra @staticmethods ( @staticmethod def a_static_method()) gelir mi? En azından anladığım şekliyle politika bu ... (bundan hoşlanmadığım için
IDE'm

2

Django'nun kaynağında gördüğüm @Ethan'a benzer bir şey yapıyorum, burada asıl fark büyük "############" alanları sınırlandırmak için yorumları engelle. Örneğin,

class SomeClass(object):
    #################
    # Magic Methods #
    #################
    def __magic_methods__(self):
        "magic methods first"

    ##################
    # Public Methods #
    ##################
    def a_method(self):
        "then normal methods, in order of importance"

    ###################
    # Private Methods #
    ###################
    def _private_method(self):
        "then worker methods, grouped by importance or related function"

Açıkçası bu, daha küçük sınıflar için daha az kullanışlıdır.


19
Ama bunların büyülü, halka açık veya özel olduklarını görebiliyorum. Ben, bu tür yorum bloklarını aktif olarak sevmiyorum; Hepsinin bir listesini görmek istersem katlanmış koda bakabilirim. İşlevsellikle ilgili belirli bir yöntem bloğunun üzerinde bir yorum yapmak, yapacağım bir şeydir, ancak bu tür bir yorum için - yöntem adlarının bana söylediği şey budur.
Chris Morgan

Yine, bunu yalnızca daha büyük sınıflar için yapıyorum. Sihirli yöntemleri yarı özel ( ) ve adı karıştırılmış (_ ) yöntemlerle karıştırmanın kolay olduğunu düşünüyorum .
Matt Luongo

Düzenlemenin ortasında, çirkin ####blokları kaldırıyordum, onları oraya bilerek koyduğunu anladım ! Yine de emre katılıyorum , bu sorunun konusu da bu. ####Sorunun kapsamıyla ilgili olmadığı ve örneğiniz küçük bir sınıfa ait olduğu ve ####zaten kullanmayacağınız için bu örnekten çıkarmanızı öneririm . :-)
Mateen Ulhaq

1
@MateenUlhaq lütfen düzenleme ekranında görüntülenen ikinci ve beşinci yönergelere bakın: "anlamı değiştirmeden anlamı netleştirin" ve " her zaman orijinal yazara saygı gösterin ". (Bunların, editörün kendi görüşüne bağlı olmaksızın, koşulsuz olarak uygulanması amaçlandığına dikkat edin.) Bu cevabın bütün ve tek noktası, bu çirkin yorum bloklarını göstermekti; onlar olmadan, Ethan'ın cevabıyla tamamen aynı şeyi söylüyor ve burada olmasının bir anlamı yok. Hatta blokların " kasıtlı olarak " orada olduğunu bile kabul ettiniz - bunu bilerek, neden gidip onları kaldırdınız?
hallo

1
@MIWright Bunu sorunun kapsamı dışında düşündüm. Gördüğünüz gibi rev2 , soruyu Ethan'ınkinden farklı bir şekilde, farklı bir sıralama (ve alt sırayla!) Yine de geri döndü.
Mateen Ulhaq
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.