Get / set modelini (Python'da) kullanıyor musunuz?


82

Get / set kullanımı Java'da yaygın bir uygulama gibi görünüyor (çeşitli nedenlerle), ancak bunu kullanan Python kodunu pek görmüyorum.

Python'da get / set yöntemlerini neden kullanıyorsunuz veya kullanmıyorsunuz?


Herkesten harika tepkiler. Kuşkusuz, bu soru, bu tek stackoverflow.com/questions/1022970/… ' nin bir yan ürünüdür, ancak, ona "J" sözcük perspektifinden bakan bir grup insan tarafından basılmış gibi görünüyor. Akıl sağlığına olan inancımı tazelediğin için tekrar teşekkürler ...
Avery Payne

1
Bağlam önemlidir ve burada Python ve Java tamamen farklıdır. (Ancak, Python'u başlıktan kaldırdım çünkü SO'da bunun için etiketleri kullanıyoruz.)

Yanıtlar:


59

Harika bağlantı: Python Java değil :)

Java'da, alıcılar ve ayarlayıcılar kullanmanız gerekir çünkü genel alanları kullanmak size geri dönüp fikrinizi daha sonra alıcılar ve ayarlayıcılar kullanarak değiştirme fırsatı vermez. Yani Java'da, işi baştan halledebilirsin. Python'da bu aptalca çünkü normal bir öznitelikle başlayabilir ve sınıftaki hiçbir müşteriyi etkilemeden fikrinizi istediğiniz zaman değiştirebilirsiniz. Yani, alıcılar ve ayarlayıcılar yazmayın.


3
artı ayarlayıcılar / alıcılar, özellikle Python'da performans maliyeti ekler.
Nick Dandoulakis

4
Bu , örnek değişkenleri dolaylı olarak sınıfın genel API'sinin bir parçası haline geldiği için sınıf tasarımcısına ek bir yük getirir. Bir sınıfı düzenlerken, sınıf uygulamanızın gerçekten yalnızca bir parçası olanlara karşı dışarıdan erişmek istediğiniz örnek değişkenlerini açıkça düşünün. Dahili uygulamaların önüne bir '_' ekleyin. Bu, uygulama değişirse bu değişkenin de değişebileceğini veya hatta tamamen ortadan kalkabileceğini belirten Python uyarı işaretidir. Aksi takdirde, uygulama bilgisinin sınıfınızdan sızdığını ve daha sonra değiştirilmesini zorlaştırdığını göreceksiniz.
PaulMcG

8
@Nick D: Erişimcilerin Python'da hız optimizasyonları yapmak için doğru yer olduğunu düşünmüyorum.
wRAR

1
@Nick D: Demek istediğim, bu, performansı değil okunabilirliği teşvik eden yorumlanmış bir dil, dolayısıyla bir programda optimizasyonlar için çok daha iyi yerler olacak.
wRAR

2
@Paul: Bir veya iki önde gelen alt çizgi ile adlandırılmadığı sürece dahili bir özellik değildir (ilk biçim genellikle ikincisi Python'un alışılmadık adını karıştırdığı için tercih edilir). Doküman yazmak istemiyorsanız ve bu sorun sizi rahatsız ediyorsa, tüm örnek öznitelikleri için varsayılan olarak _name kullanın.

113

Python'da, özniteliğe doğrudan erişebilirsiniz çünkü o geneldir:

class MyClass:

    def __init__(self):
        self.my_attribute = 0  

my_object = MyClass()
my_object.my_attribute = 1 # etc.

Eğer özelliğin erişim veya mutasyon üzerine bir şeyler yapmak istiyorsanız, kullanabileceğiniz özellikler :

class MyClass:

    def __init__(self):
        self._my_attribute = 0

    @property
    def my_attribute(self):
        # Do something if you want
        return self._my_attribute

    @my_attribute.setter
    def my_attribute(self, value):
        # Do something if you want
        self._my_attribute = value

En önemlisi, müşteri kodu aynı kalır.


30

Guido van Rossum, Masterminds of Programming kitabında bunun hakkında söyledikleri

"Dil ile savaşmak" derken neyi kastediyorsunuz?

Guido: Bu genellikle, işe yarayan alışkanlıklarını farklı bir dille sürdürmeye çalıştıkları anlamına gelir.

[...] İnsanlar her şeyi bir sınıfa dönüştürecek ve her erişimi bir erişimci yöntemine çevirecek,
burada bu Python'da yapılacak pek akıllıca bir şey değildir;
hata ayıklaması daha zor olan ve çok daha yavaş çalışan daha ayrıntılı kodlara sahip olacaksınız . "FORTRAN'ı herhangi bir dilde yazabilir misin?" İfadesini biliyorsunuz. Java'yı herhangi bir dilde de yazabilirsiniz.


14

Hayır, ruhani değil. Genel olarak kabul edilen yol, normal veri özniteliğini kullanmak ve daha karmaşık get / set mantığı gerektirenleri özelliklerle değiştirmektir.


13
+1: "Burada hepimiz yetişkiniz". Kod görülebilir. "özel" ve "alıcı / ayarlayıcı" kodun tamamı görülebildiğinde herhangi bir değer yaratmaz.
S. Lot

7

Sorunuzun kısa cevabı hayır, gerektiğinde özellikleri kullanmalısınız. Ryan Tamyoko, Getters / Setters / Fuxors adlı makalesinde uzun cevabı veriyor.

Tüm bunlardan uzaklaşmanın temel değeri, her bir kod satırının programcı için bir değeri veya anlamı olduğundan emin olmak istemenizdir. Programlama dilleri makineler içindir, insanlar içindir. Yararlı bir şey yapmayan, okunması zor veya sıkıcı görünen bir kodunuz varsa, Python'un onu kaldırmanıza izin verecek bir dil özelliğine sahip olma ihtimali yüksektir.


5

Gözleminiz doğru. Bu normal bir Python programlama tarzı değildir. Özniteliklerin tümü geneldir, bu nedenle bunlara sahip olan herhangi bir nesnenin özniteliklerine (yalnızca sınıflar veya örnekler değil) olduğu gibi erişirsiniz (alma, ayarlama, silme). Java programcılarının Python'u öğrendiklerinde bunu söylemek kolaydır çünkü Python kodları Java sözdizimi kullanan Java'ya benzer!

Önceki tüm posterlere, özellikle @ Maximiliano'nun Phillip'in ünlü makalesine olan bağlantısına kesinlikle katılıyorum. ve @ Max'in, sınıf ve örnek niteliklerini belirlemenin (ve elde etmenin) standart yolundan daha karmaşık bir şeyin Özellikler'i (veya daha fazla genelleştirmek için Tanımlayıcıları) kullanmak olduğu yönündeki önerisine . özelliklerin alınmasını ve ayarlanmasını özelleştirmek için! (Bu, kendi özelleştirilmiş özel, korumalı, arkadaş sürümlerinizi veya genel dışında bir şey istiyorsanız, istediğiniz herhangi bir politikayı ekleyebilmeyi içerir.)

İlginç bir demo olarak, Core Python Programming'de (bölüm 13, bölüm 13.16), öznitelikleri bellekte değil diske depolamak için tanımlayıcıları kullanma örneğini buldum !! Evet, tuhaf bir kalıcı depolama biçimi, ancak does size mümkündür dair bir örnek göstermek!

İşte yararlı bulabileceğiniz başka bir ilgili gönderi: Python: birden çok özellik, bir ayarlayıcı / alıcı


0

Buraya o cevap için geldim (maalesef yapamadım). Ama başka bir yerde bir buldum . Aşağıdaki kod, get için alternatif olabilir .
class get_var_lis: def __init__(self): pass def __call__(self): return [2,3,4] def __iter__(self): return iter([2,3,4]) some_other_var = get_var_lis
Bu yalnızca bir çözümdür . Yukarıdaki kavramı kullanarak, py'de de kolayca get / set metodolojisi oluşturabilirdiniz.


-10

Öğretmenimiz, erişim işlevlerini ne zaman kullanmamız gerektiğini açıklayan sınıfta bir örnek gösterdi.

class Woman(Human):
    def getAge(self):
        if self.age > 30:
            return super().getAge() - 10
        else:
            return super().getAge()

Size olumsuz oyları vermedim, ama ben de harekete geçeceğimi düşündüm. Tartışmanın amacı, "özelliklere doğrudan Python'da erişmek için neden get () / set () ihtiyacımız var". Java'da, bunu arzu edilir kılan ... dil özellikleri vardır. Python'da pek değil.
Avery Payne

7
Soruyu gerçekten cevaplamamanın yanı sıra, bu cevapta kullanılan örnek saldırgan. Öğretmeninizin onu kullandığı iddiası cinsiyetçiliğini haklı çıkarmaz.
Touzen

Bunun cinsiyetçiliği gösterdiğinden şüpheliyim, sadece saflığını. Büyükannemin neslinde birçok kadın, yaşlarının gerçekte olduğundan birkaç yaş daha genç olduğu konusunda şaka yaptı. Üstelik cevapla hiçbir ilgisi yok zaten.
Johan Snowgoose
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.