簡體   English   中英

Python中的變量函數調用

[英]Variable function calling in Python

Instrument是具有以下三個功能的類: piano(self)guitar(self)trumpet(self) 該類還具有play(self)函數,該函數將根據類中表示的樂器調用適當的方法。

有沒有一種方法,只有一個類Instrument (即沒有其他抽象類),可以定義在調用play方法時應調用的方法?

換句話說,有沒有一種方法可以執行以下操作:

my_piano = Instrument(piano)
my_piano.play() # calls piano(self) method

my_guitar = Instrument(guitar)
my_guitar.play() # calls guitar(self) method

my_trumpet = Instrument(trumpet)
my_trumpet.play() # calls trumpet(self) method

一個相當簡單的方法(但不是很干凈的代碼)是在構造函數中放置一個變量,然后在play方法中放置很多條件,如下所示:

def Instrument(object):
    def __init__(self, instrument_type):
        self.instrument_type = instrument_type

    def play(self):
        if instrument_type == 0:
            self.piano()
        elif instrument_type == 1:
            self.guitar()
        elif instrument_type == 2:
            self.trumpet()

正確的方法是先擁有Instrument類,然后再繼承從Instrument繼承的三個PianoGuitarTrumpet類。 但是出於我的需要,這只會使事情復雜化。

編輯

根據要求,我解釋了我的實際問題,該問題幾乎是相同的。 我有一個ComputeSth類,可以使用五種不同的方法來計算該東西。 它可以通過a(self)b(self) ,..., f(self) 例如,有時我想根據a計算,而另一些時候根據c 如果我這樣做,那很容易:

my_computer = ComputeSth()
my_computer.a()
my_computer.c()

但是后來我注意到,為了在代碼的其他部分輕松使用此類,我更喜歡使用my_computer.compute() 因此,我認為在調用compute(self)時使用實際的計算方法構造實例將很方便。 我不想編寫其他五個類,因為它們實際上並不表示五個不同的對象,而是五個表示相同對象的方法。 我不能將函數a ,..., f作為構造函數的輸入傳遞,因為require是self
換句話說,與Instrument的示例相同,但“現實世界繼承”較少。

這就是多態性的目的

class Instrument:

  def play(self):
    pass

class Guitar(Instrument):

  def play(self):
    print 'brau dau'

class Drum(Instrument):

  def play(self):
    print 'dum dum'


guitar = Guitar()
guitar.play()

drum = Drum()
drum.play()

這肯定是錯誤的設計,但絕對可行:

class Instrument:
    def __init__(self, method):
        self.method = method

    def play(self):
        self.method(self)

    def piano(self):
        print("I am a piano")

    def trumpet(self):
        print("I am a trumpet")

    def guitar(self):
        print("I am a guitar")

piano = Instrument.piano
trumpet = Instrument.trumpet
guitar = Instrument.guitar

my_piano = Instrument(piano)
my_piano.play()
#... and others

你傳遞一個綁定類方法的__init__儀,然后在play調用上的方法self

您甚至可以通過創建獨立功能來擴展可用的工具

def violin(self):
    print("I am playing a violin")

my_violin = Instrument(violin)
my_violin.play()

但是上面顯示的整個方法在python世界中確實很少使用。

如果您確實不想建立類層次結構,則可以在enum類中定義所有可能的類型,然后選擇正確的方法。 為了避免if語句,您可以使用字典:

In [1]: import enum

In [2]: class InstrumentType(enum.Enum):
   ...:     PIANO = 0
   ...:     GUITAR = 1
   ...:     TRUMPET = 2
   ...:     

In [3]: class Instrument:
   ...:     def __init__(self, type):
   ...:         self.type = type
   ...:     def piano(self):
   ...:         print('Piano')
   ...:     def guitar(self):
   ...:         print('Guitar')
   ...:     def trumpet(self):
   ...:         print('Trumpet')
   ...:     def play(self):
   ...:         return {
   ...:             InstrumentType.PIANO: self.piano,
   ...:             InstrumentType.GUITAR: self.guitar,
   ...:             InstrumentType.TRUMPET: self.trumpet
   ...:         }.get(self.type, lambda: print('Not an instrument'))()
   ...:     

In [4]: guitar = Instrument(InstrumentType.GUITAR)

In [5]: guitar.play()
Guitar

In [6]: unknown = Instrument('UNKNOWN')

In [7]: unknown.play()
Not an instrument

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM