2015-03-24 17 views
8

Şu anda büyük ölçüde aynı şeyi yapan bir dizi adımda yineleme yapmanız gereken bir uygulama yapıyorum, çok az miktarda kod (~ 15 satır) kaydedin. Adım sayısı, projenin nasıl yapılandırıldığına bağlı olarak değişecektir, bu yüzden her bir potansiyel örnek için ayrı bir işlev oluşturmam benim için aptalca görünebilir.Sözlükde İşlevleri Kaydetme [Python]

var switches = [true, true, false, true]; 

var holder = { 
    0: function() { /* do step0 */ } 
    1: function() { /* do step1 */ } 
    2: function() { /* do step2 */ } 
    3: function() { /* do step3 */ } 
    // ...etc... 
} 

for (var i = 0; i < switches.length; i++) 
    if (switches[i]) 
     holder[i](); 

python buna benzer bir şey yapmak için bir yolu var mı:

JavaScript'inizde

, böyle bir şey yapsın ki? Ben adımların herhangi önemli sayıda varsa

switches = [True, True, False, True] 

class Holder(object): 
    @staticmethod 
    def do_0(): 
     # do step0 

    @staticmethod 
    def do_1(): 
     # do step 1 

    # ...etc... 

    def __repr__(self): 
     return [self.do_0, self.do_1, ...] 

for action in Holder: 
    action() 

Bu sadece korkunç verimsiz görünmektedir: Aklıma gelen tek şey böyle bir şeydir. Bu konuda daha iyi bir yolu var mı? aşağıdaki gibi

+0

Bir dekoratör ne istediğine uygun olabilir –

+0

Bunu yapmanın en iyi yolu ne olurdu? Tüm fonksiyonları aynı dekoratörle tanımlarım halinde, içinden geçecek bir liste oluşturmadan, bunlarla döngü yapmanın kolay bir yolu var mı? –

cevap

2

görünüyor Python'da bunu yapmak için bir yol yok gibi, bir Pythonic olarak reddedildiğinden beri bilerek yapılan bir tasarım kararı. Oh, sanki, yöntemleri tanımlamaktan sıkıldım ve daha sonra bunları tekrarlamak için bir listeye elle ekliyorum.

Kaynak: https://softwareengineering.stackexchange.com/a/99245 Genellikle aşağıdaki gibi bu konuda gitmek

3

Bunu yapabilirsin: Bu tek bir yolu

# define your functions 
def fun1(): 
    print("fun1") 

def fun2(): 
    print("fun2") 

def fun3(): 
    print("fun3") 


switches = [True, False, True]; 

# put them in a list (list makes more sense than dict based on your example) 
func_list = [fun1, fun2, fun3] 

# iterate over switches and corresponding functions, and execute 
# functions when s is True  
for s,f in zip(switches, func_list): 
    if s: f() 

olduğunu. Diğerleri çok var. Örneğin. senin fonksiyonları tek hat sadece eğer istediğiniz gibi lambdas kullanmak için, vb

dicti lambdas kullanarak bunu yapabilirsiniz:

func_list = [lambda: print("lambda1"), 
      lambda: print("lambda2"), 
      lambda: print("lambda1")] 
+1

Kodunuz kesinlikle çalışır, ancak sözlük kapsamı dışında bir dizi işlevi tanımlamaktan kaçınmaya çalışıyorum. Başka türlü sahip olduğum kodu kullanabilirim. Ne yazık ki, üzerinde çalıştığım kod, örneklemden biraz daha karmaşıktır ve kodun okunaklı hale getirilmeden bir dizi işlevi gerçekten tanımlayamadım. –

+1

Lambda örneğini ekledim. Ama her şeyi lambda'nın içine koyamazsın. – Marcin

+2

Python'un JS gibi isimsiz işlevleri yoktur. Evet, ['' lambda''] vardır (https://docs.python.org/2/tutorial/controlflow.html#lambda-expressions) s, ancak onlar tek bir ifade ile sınırlıdır. – pzp

1
- Your functions don't need to be enveloped in a utility class. 
- I don not see how the two blocks of code differ in efficiency. 
- You can use enumerate and lambdas to simplify your code. 

Basitleştirilmiş Kod

d = {0: lambda: 'Performing Step 0', 
    1: lambda: 'Performing Step 1', 
    2: lambda: 'Performing Step 2', 
    3: lambda: 'Performing Step 3', 
    4: lambda: 'Performing Step 4'} 

for index, switch in enumerate([1, 0, 1, 1, 0]): 
    if switch == 1: d[index]() 
+0

Sağladığım örnek büyük ölçüde basitleştirilmiş. Gerçek örneğimde, Tutucu sınıfı aslında adım adım işlemcimin tüm ayarlarını tutacak bir yardımcı sınıftır. Ayrıca lambdaları ilk başta kullanmayı düşündüm, ama çok karmaşık olmayacak gibi görünüyorlar (yani 15 satır kod için çalışmayacaklar). –

-1

. Bu yaklaşımı seviyorum, çünkü kod için en az yazım ek yükü ekler ve daha sonra başka bir yöntem yazarsanız, dosyanın başka bir yerinde hiçbir şeyin değiştirilmesine gerek yoktur.

def steptest0(): 
    code 
def steptest1(): 
    code 
def steptest2(): 
    code 

... 

tests = filter(lambda x: x.startswith('steptest'), 
       dir()) 
for t in tests: eval(t + '()') 

Her yöntem

zaten Python otomatik olarak sözlüğe konur ve dir() bize bu erişmenizi sağlar.

Yasal Uyarı. "Eval" göz önünde bulundurulduğunda ortalama yaya aleminin başından çıkmaya başlayan çok sayıda alarm zili ve hatta bazı nöbetler bile olabilir. Bunun yerine bir yansıma mekanizması kullanarak kendilerini değerlendirmelerini sağlayın (bu, daha az okunabilir hale getirebilir, ama yine de buna değer olur, çünkü “değerlendirmeyi” kullanmakla suçlanamazlar).

İlgili konular