Désolé pour le titre déroutant. Je pense qu'il est plus facile de comprendre ce que signifie réellement regarder le code que de l'expliquer avec des mots. En ce qui concerne l'environnement, Ruby est Ruby 2.0 et Python est Python 3.2.
Essayons d'écrire ce code en Ruby.
#Variables globales en raison de la portée
$msg = "Hello, Before World!"
def say(str = $msg)
puts str
end
say #=> Hello, Before World!
$msg = "Hello, After World!"
say #=> Hello, After World!
La sortie doit être comme commentée.
Si vous écrivez un code similaire en Python, il ressemblera à ceci.
msg = "Hello, Before World!"
def say(str = msg):
print(str)
say() #=> Hello, Before World!
msg = "Hello, After World!"
say() #=> Hello, Before World!
Le code est similaire, mais la sortie de la fonction «say» a changé.
Avez-vous une idée générale du titre?
Premièrement, Ruby et Python peuvent écrire des expressions arbitraires dans les valeurs d'argument par défaut. Ainsi, le moment auquel cette valeur est évaluée diffère entre Ruby et Python.
Dans Ruby, ** lorsqu'une fonction est appelée **, En Python, la valeur de l'argument par défaut est évaluée lorsque ** la fonction est définie **.
$msg = "Hello, Before World!"
def say(str = $msg)
puts str
end
say() #=> Hello, Before World!
$msg = "Hello, After World!"
say() #=>avec ce timing$msg est évalué
#=>Alors bonjour, After World!
msg = "Hello, Before World!"
def say(str = msg): #À ce stade, msg est évalué Bonjour, Before World!Il est devenu
print(str)
say() #=> Hello, Before World!
msg = "Hello, After World!"
say() #=>Bonjour car la valeur de str a déjà été décidée, Before World!
Donc, le résultat est le même qu'avant.
Personnellement, je pense que Ruby est plus intéressant car il peut faire diverses choses, mais les deux comportements sont * naturels *, donc ce n'est pas mal. (Je me demande si Python doit le faire à cause des spécifications de la VM)
Au fait, dans Ruby, vous pouvez faire référence à des arguments autres que l'argument par défaut, donc en s'appelant dans l'argument par défaut et en le rendant récursif,
#Ecoute, ce type récursivement avec les arguments par défaut ...
def fact(n,ret = n <= 1 ? 1 : fact(n-1) * n)
ret
end
puts fact(10) #=> 3628800
Vous pouvez faire quelque chose comme ça. Ruby est ... (excusez-moi).
Au fait, il semble que Python utilise cette propriété pour remplacer la portée locale (probablement).
say_n = []
for i in range(0,10):
#say_n.append(lambda: print(i))
#Si tel est le cas, la valeur de i sera mise à jour, il est donc inutile
say_n.append(lambda j = i: print(j))
#J'ai besoin de lier j'aime ça
say_n[2]() #=> 2
say_n[4]() #=> 4
C'était une astuce très diverse, mais si vous devenez accro à d'aussi petites différences dans les spécifications pour chaque langue, vous ne pourrez pas vous en sortir facilement, donc je pense que ce n'est pas une perte de savoir. J'espère que vous vous en souvenez et que vous trouverez quelque chose d'utile.
Puisque Ruby et Python sont tous deux des étrangers, il peut y avoir des erreurs. Si vous le trouvez, j'apprécierais que vous mordiez gentiment Hatoo dans les commentaires ou sur Twitter ([@ alucky0707]).
Recommended Posts