SORU
30 HAZİRAN 2009, Salı


____ __yerine lt cmp__

Python 2.x aşırı yük karşılaştırma operatörleri, __cmp__ iki yolu veya "zengin karşılaştırma operatörleri" __lt__ gibi.Zengin karşılaştırıldığında aşırı tercih olduğu söyleniyor, ama neden böyle?

Zengin karşılaştırma operatörleri basit her uygulamak için vardır, ama hemen hemen aynı mantık ile onları çeşitli uygulamak gerekir. Eğer yerleşik cmp kullanımı ve sipariş demet eğer varsa, o zaman __cmp__ oldukça basit olur ve tüm karşılaştırmalar yerine getirir:

class A(object):
  def __init__(self, name, age, other):
    self.name = name
    self.age = age
    self.other = other
  def __cmp__(self, other):
    assert isinstance(other, A) # assumption for this example
    return cmp((self.name, self.age, self.other),
               (other.name, other.age, other.other))

Bu sadelik benim ihtiyaçlarımı her zaman için daha iyidir 6 aşırı daha karşılayacak gibi görünüyor(!) zengin karşılaştırmaları. (Ancak, sen-ebilmek almak için "sadece" 4 Eğer size güveniyor "takas değişken"/yansıyan davranış, ama sonuçlar bir net Artış komplikasyonu, benim naçizane görüşüm.)

Herhangi bir beklenmedik tuzaklar ben sadece aşırı __cmp__ eğer farkında olması gereken var mı?

, *, ==, *<=10 vb anlıyorum. operatörler başka amaçlar için tahsis edilebilir, ve onlar gibi herhangi bir nesne döndürür. Sadece sayılar için yani aynı anlamda karşılaştırma için bu operatörleri kullanırken farklar hakkında, bu yaklaşımın yararları hakkında, ama sormuyorum.

Güncelleme:pointed out, cmp Kristof 3 içinde yok oluyor.x.Uygulama karşılaştırmalar kadar kolay yukarıdaki __cmp__ herhangi bir alternatif var mı?

CEVAP
30 HAZİRAN 2009, Salı


Evet, kolay kendisine dahil ederse, bir sınıf (ya da bir metaclass, ya da eğer tadı bu şekilde çalışıyorsa sınıf bir dekoratör) ** 15 * açısından her şeyi uygulamak.

Örneğin:

class ComparableMixin:
  def __eq__(self, other):
    return not self<other and not other<self
  def __ne__(self, other):
    return self<other or other<self
  def __gt__(self, other):
    return other<self
  def __ge__(self, other):
    return not self<other
  def __le__(self, other):
    return not other<self

Şimdi sınıfınızın sadece __lt__ tanımlamak ve ComparableMixin neyse sonra diğer ihtiyaçları üsleri, (varsa) miras çarpın. Bir sınıf dekoratör olurdu oldukça benzer, sadece ekleme benzer işlevler, öznitelikleri, yeni bir sınıf, bu dekorasyon (sonucu olabilir mikroskobik hızlı çalışma zamanında, eşit dakika maliyet açısından bellek).

Elbette, eğer sınıfınız var biraz özellikle hızlı bir şekilde uygulamak için (örneğin) __eq__ __ne__ gerektiğini tanımlamak onları doğrudan bu yüzden kendisine dahil ederse, bu sürümleri kullanmak (örneğin, bu durumda dict) -- aslında __ne__ belki iyi tanımlanmış kolaylaştıracak gibi

def __ne__(self, other):
  return not self == other

ama devam etmek istedim yukarıdaki kodu kullanarak hoş sadece simetri <;-). Biz bu yana __cmp__ gitmek zorunda kaldı neden olarak,yaptıbir başka neden sürekli __lt__ ve arkadaşlar, tam olarak yapmak için farklı bir şekilde aynı şey var mı? Sadece bu kadar her Python zamanı-kilo öldü (Klasik, Jython, IronPython, PyPy, ...). Kod bukesinlikleolmayacak hatalar var kod yok -- nereden Python prensibi bu olmalı ideal olarak belirgin bir şekilde gerçekleştirmek için bir Görev (C aynı prensipte "Ruh " C" bölümünde ISO standart, btw).

Bu yolumuzdan şeyleri yasaklar gidiyoruz (örneğin, yakın eşdeğerlik mixins ve sınıf dekoratörler arasında bazı kullanımlar için), ama kesinlikle anlamına gelmezyokgereğinden tam olarak aynı görevi gerçekleştirmek için birden fazla eşdeğer yaklaşımları desteklemek için var olan bir soğutucu ve/veya çalıştırıcısı kod taşımak istemiyoruz.

Daha da edit: yok aslında daha iyi bir şekilde sağlamak, karşılaştırma VE karma sınıflar da dahil olmak üzere bu soruyu -- __key__ yöntem, ben de belirttiğim gibi benim yorum soru. Hiç denemedim için KEP yazmaya başladığından beri, şu anda Eğer isterseniz bir kendisine dahil ederse (&c) ile uygulamak gerekir:

class KeyedMixin:
  def __lt__(self, other):
    return self.__key__() < other.__key__()
  # and so on for other comparators, as above, plus:
  def __hash__(self):
    return hash(self.__key__())

Bu çok sıradan bir dava için bir örneğinin karşılaştırmalar ile diğer örneklerine kurutan karşılaştıran bir satır için her ile bir kaç tarla ve sonra, karma olmalı uygulanan aynı temel. __key__ özel yöntemi doğrudan ihtiyaca cevap verir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • chrmoe

    chrmoe

    7 Kasım 2006
  • ShotgunSandwichENT

    ShotgunSandw

    3 EKİM 2012
  • steeletraining

    steeletraini

    28 NİSAN 2010