2017-03-14 1 views
0

Comme ruby, comment passer le bloc de code et le faire exécuter (rendement) où vous le passez. J'essaye d'accomplir la même chose dans python 3.5 C'est à quoi ressemble mon code pseudo. Comment réaliser ce que j'essaie de faire. Quels changements devrais-je faire?Comment faire Python méta programmation pour passer des blocs de code autour (comme le rendement Ruby)

# Calculate all 
# I want this function should yield whatever method passed to it 

# THIS MUST BE A CLASS 
class Calculator: 

    def __init__(self): 
    self.prefix = "hello" 

    def calculate(self, function_name) 
    local_val = 10 
    print("executing {} function with {}".format(function_name, self.prefix)) 
    result = function_name(local_val) 
    print(result) 
    return result 



# I want to pass these functions to Calculator().calculate() method 

def add_one(x): 
    return x+1 

def minus_one(x): 
    return x-1 

def divide_in_half(x): 
    return x/2 



Calculator().calculate(add_one(?)) 
# expect this to print: 
# executing add_one function with hello 
# 11 


Calculator().calculate(minus_one(?)) 
# expect this to print: 
# executing minus_one function with hello 
# 9 

Calculator().calculate(divide_in_half(?)) 
# expect this to print: 
# executing divide_in_half function with hello 
# 5 
+0

Il semble que votre 'Calculator' n'a pas besoin d'être une classe du tout ... –

Répondre

1

fonctions sont des objets en Python, vous pouvez donc tout faire:

Calculator().calculate(add_one) 
Calculator().calculate(minus_one) 
Calculator().calculate(divide_in_half) 

Notez que ce passe la fonction elle-même et non le nom de la fonction. (Dans votre code, vous devez accéder function_name.func_name pour obtenir le nom de la fonction, je vous conseille donc de renommer function_name-fn, qui est l'abréviation de « fonction ».)

Vous ne même pas besoin de déclarer des fonctions prédéfinies. Vous pouvez utiliser la syntaxe lambda pour passer un anonyme appelable à la volée:

# Instead of add_one, for example: 
Calculator().calculate(lambda x: x + 1) 
+0

Merci @cdhowie – JVK

1

Dans un premier temps, fixer votre __init__ il ne se plaint pas quand appelé sans args:

def __init__(self, prefix="hello") 

utiliser la fonction __name__ dans l'appel à format fait en calculate:

msg = "executing {} function with {}" 
print(msg.format(function_name.__name__, self.prefix)) 

passe ensuite les objets fonctionnels le long de:

Calculator().calculate(add_one) 
# expect this to print: 
# executing add_one function with hello 
# 11 


Calculator().calculate(minus_one) 
# expect this to print: 
# executing minus_one function with hello 
# 9 

Calculator().calculate(divide_in_half) 
# expect this to print: 
# executing divide_in_half function with hello 
# 5 
+0

Merci pour la réponse @ Jim – JVK