SORU
22 HAZİRAN 2011, ÇARŞAMBA


Python fonksiyon aşırı yükleme

Bu Python yöntemi aşırı desteklemiyor biliyorum, ama güzel Pythonic bir şekilde çözmek için görünmüyor olabilir, bu bir sorun haline koşuyoruz.

Bir karakter mermi çeşitli ateş gereken bir oyun yapıyorum, ama nasıl bu mermi oluşturmak için farklı fonksiyonlar yazılır? Belirli bir hız ile bir kurşun B noktası A Seyahat oluşturan bir işlevi var örneğin varsayalım. Böyle bir fonksiyon yazmak istiyorum:

    def add_bullet(sprite, start, headto, speed):
        ... Code ...

Ama mermi oluşturmak için: diğer fonksiyonlar yazmak istiyorum

    def add_bullet(sprite, start, direction, speed):
    def add_bullet(sprite, start, headto, spead, acceleration):
    def add_bullet(sprite, script): # For bullets that are controlled by a script
    def add_bullet(sprite, curve, speed): # for bullets with curved paths
    ... And so on ...

Ve bu yüzden birçok varyasyonları ile. Daha iyi bir yol, pek çok anahtar kelime argümanlar almak onun biraz neden çirkin hızlı kullanarak olmadan bunu yapmak için var. Her bir işlevin yeniden adlandırma add_bullet1, add_bullet2 add_bullet_with_really_long_name her iki elde de çok kötü.

Bazı cevaplar adresi için:

  1. Çok yavaş çünkü Kurşun sınıf bir hiyerarşi oluşturmak mümkün değil. Yönetmek için gerçek mermi kodu C ve işlevleri etrafında C API sarıcıları.

  2. Parametreleri kombinasyonları her türlü için ilgili anahtar kelime argümanlar ama kontrol can sıkıcı oluyor biliyorum ama varsayılan bağımsız değişkenleri acceleration=0 gibi tahsis yardımcı olur

CEVAP
22 HAZİRAN 2011, ÇARŞAMBA


Python desteği "yöntemi aşırı bunu sana hediye olarak". Sadece tarif ne kadar çok farklı şekillerde aslında, önemsiz Python uygulamaktır, ama şunu söyleyebilirim ki:

class Character(object):
    # your character __init__ and other methods go here

    def add_bullet(self, sprite=default, start=default, 
                 direction=default, speed=default, accel=default, 
                  curve=default):
        # do stuff with your arguments

Yukarıdaki kodu, default bu tartışmalar için makul bir varsayılan değeri, ya da None. Daha sonra ilgilenen tek argüman olmadan yöntemini çağırabilirsiniz, ve Python varsayılan değerleri kullanacaktır.

Ayrıca şöyle bir şey yapabilirsin:

class Character(object):
    # your character __init__ and other methods go here

    def add_bullet(self, **kwargs):
        # here you can unpack kwargs as (key, values) and
        # do stuff with them, and use some global dictionary
        # to provide default values and ensure that ``key``
        # is a valid argument...

        # do stuff with your arguments

Başka bir seçenek, doğrudan sınıf veya örnek için istenen işlev kanca:

def some_implementation(self, arg1, arg2, arg3):
  # implementation
my_class.add_bullet = some_implementation_of_add_bullet

Henüz başka bir yolu soyut fabrika deseni kullanmak için:

class Character(object):
   def __init__(self, bfactory, *args, **kwargs):
       self.bfactory = bfactory
   def add_bullet(self):
       sprite = self.bfactory.sprite()
       speed = self.bfactory.speed()
       # do stuff with your sprite and speed

class pretty_and_fast_factory(object):
    def sprite(self):
       return pretty_sprite
    def speed(self):
       return 10000000000.0

my_character = Character(pretty_and_fast_factory(), a1, a2, kw1=v1, kw2=v2)
my_character.add_bullet() # uses pretty_and_fast_factory

# now, if you have another factory called "ugly_and_slow_factory" 
# you can change it at runtime in python by issuing
my_character.bfactory = ugly_and_slow_factory()

# In the last example you can see abstract factory and "method
# overloading" (as you call it) in action 

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AllYourNewsByMe

    AllYourNewsB

    18 Temmuz 2011
  • Kai Moosmann

    Kai Moosmann

    5 Temmuz 2006
  • Tire Rack

    Tire Rack

    31 Mayıs 2007