Comment puis-je exécuter une fonction stockée en tant que valeur de dictionnaire avec des arguments précis?

Je suis en train de mettre en œuvre une coutume cas de commutateur en Python à l'aide de dictionnaires pour une poignée de joueur de saisie de texte, base de jeu. Mon idée est de dresser la carte d'entrée du lecteur à une fonction correspondante, qui est simple dans la théorie, à la recherche de quelque chose comme ceci:

def foo():
    print("foo")

def bar():
    print("bar")

dic = {"foo":foo, "bar":bar}

action = input("> ")
function = dic.get(action)
function()

les sorties de ce que vous attendez de la fonction correspondante, par exemple "toto" à partir de la fonction foo avec l'entrée "foo".

Cependant, dans la pratique, le problème se pose lorsque j'ai besoin de passer les arguments spécifiques à chaque fonction. Lors de l'ajout de parenthèses à une fonction dans le dictionnaire pour spécifier des arguments, comme vous le savez tous, exécute la fonction au lieu de les stocker, c'est à dire en modifiant le code ci-dessus pour

def foo():
    print("foo")

def bar():
    print("bar")


action = input("> ")

dic = {"foo":foo(),"bar":bar()}

function = dic.get(action)
function()

exécute les deux foo() et bar(), indépendamment de l'entrée.

Ma fonction actuelle se présente comme suit:

def get_action(arg1, arg2, arg3):
    # -----INPUT-----
    action = input("> ").lower()

    possible_actions = {
        "foo":foo(arg1),
        "bar":bar(arg2),
        "foobar":foobar(arg2, arg3)
        }

    # execute function that corresponds to the action from the switch case
    action_to_execute = possible_actions.get(action)
    action_to_execute()

Comment puis-je changer cela pour que je puisse stocker les fonctions correctement et arguments d'entrée en cas de besoin?

0
2019-09-17 21:28:02
source
1 réponses

Tout d'abord, vous faites beaucoup de choses, même si vous n'êtes pas dans le POST de cas. Je vous suggère de vérifier si vous êtes en POSTE ou non.

if request.method == 'POST':

Si vous êtes en POSTE, vous pouvez récupérer le formulaire avec :

form = RegisterForm(request.POST)

si vous n'êtes pas en POSTE, vous devez envoyer un formulaire vide à la page :

form = RegisterForm()

Puis, après avoir vérifié que le formulaire est valide, vous pouvez déjà créer un nouvel utilisateur.

user = User()

Notez que vous devez importer la classe Utilisateur : from django.contrib.auth.models import User Maintenant, vous pouvez récupérer des données à partir de votre forme comme vous l'avez fait, et de l'assigner à votre nouvel Utilisateur vide:

user.username = form.cleaned_data.get('username')
user.email = form.cleaned_data.get('email')

Pour le mot de passe, vous devez chiffrer avec :

user.password = make_password(form.cleaned_data.get('password'))

Notez que vous devez importer le make_password méthode : from django.contrib.auth.hashers import make_password

Après tout cela, vous pouvez enregistrer votre nouveau compte d'utilisateur pour la base de données :

user.save()

Notez que vous devriez probablement faire de l'enregistrer dans un try: ... except bloc dans le but de repérer d'éventuels exception provoquée par IntegrityError si plusieurs utilisateurs essaient de vous inscrire avec le même nom d'utilisateur ou une telle, selon les règles d'Intégrité que Django utilise pour son modèle d'Utilisateur par défaut (dont je ne me souviens pas)

Enfin, votre vue doit ressembler à ça (ou similaire) :

def register_page(request):
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid():
            user = User()
            user.username = form.cleaned_data.get('username')
            user.email = form.cleaned_data.get('email')
            user.password = make_password(form.cleaned_data.get('password'))
            user.save()
    else:
        form = RegisterForm()
    return render(request, 'auth/register.html', {'form': form})

Il doit travailler en considérant que vous avez fait votre importations, une bonne RegisterForm, et un bon auth/register.html

+2
2019-09-17 21:33:29

Voir d'autres questions sur les étiquettes