2012-02-09 3 views
2

Je fais des recherches en ligne depuis un moment maintenant et je n'arrive pas à trouver quoi que ce soit. J'apprends fondamentalement quelques langues et j'essaye juste de recréer un programme dans différentes langues.Passer des variables en Python

def read_one_file(): 
    f = open('C:\Python27\inventory.dat', 'r') 
    invid = f.readline() 
    stock = f.readline() 
    published = f.readline() 
    price = f.readline() 
    invtype = f.readline() 
    title = f.readline() 
    author = f.readline() 
    return invid, stock, published, price, invtype, title, author 

read_one_file() 

print "Update Number In Stock" 
print "----------------------" 
print "Item ID: ", invid 

Fondamentalement, je suis en train de lire dans un fichier, absorber les données dans les variables puis passer ces variables à la principale (classe?). Quand je les retourne, ils ne peuvent toujours pas être imprimés. Quand je les initialise en dehors de read_one_file, ils ne retournent toujours pas la bonne chose.

Répondre

5

Vous devez stocker les résultats de read_one_file() quelque part. Qu'est-ce que vous êtes vraiment faire avec votre déclaration de retour est la création d'un tuple des résultats. Vous devez ensuite décompresser ce tuple lorsque vous appelez read_one_file. Voici un exemple:

(invid, stock, published, price, invtype, title, author) = read_one_file() 

print "Item ID:", invid 

Cette syntaxe effectue quelque chose appelé « pattern matching » et ce qu'il fait est briser le tuple qui read_one_file les retours et donne des noms à chacun des éléments en elle. J'ai ajouté la parenthèse ici pour plus clairement que read_one_file retourne un tuple, mais vous pouvez tout aussi facilement écrire comme ceci:

invid, stock, published, price, invtype, title, author = read_one_file() 

C'est bien beau, mais vraiment, c'est une sorte de mauvaise façon de retourner les choses de votre fonction. Si vous avez beaucoup de variables que vous voulez renvoyer d'une fonction comme celle-ci, une dict est probablement une meilleure façon de procéder. En outre, vous voudrez probablement utiliser une instruction with pour vous assurer que votre fichier est fermé et nettoyé correctement une fois que vous avez terminé. Voici ce que votre code ressemblerait en utilisant cette stratégie:

def read_one_file(): 
    with open('C:\Python27\inventory.dat', 'r') as f: 
     return dict(invid = f.readline().strip(), 
        stock = f.readline().strip(), 
        published = f.readline().strip(), 
        price = f.readline().strip(), 
        invtype = f.readline().strip(), 
        title = f.readline().strip(), 
        author = f.readline().strip()) 

results = read_one_file() 

print "Update Number In Stock" 
print "----------------------" 
print "Item ID: ", results['invid'] 

Edit: depuis (. @NiklasB comme souligné), j'ai changé le code ci-dessus pour utiliser .strip(), les nouvelles lignes sont toujours inclus avec juste readline.

+0

Ce n'est pas trop sec ... Aussi, il préserve toutes les nouvelles lignes présentes dans le fichier. –

+3

+1 pour répondre à la question d'une manière que le répondant peut comprendre. N'allons pas trop loin devant le public, @NiklasB. – mattbornski

+0

Eh bien, j'allais plus à partir d'un 'voici quelques améliorations que vous pouvez apporter à votre code' afin qu'il n'ait pas à chercher trop pour le comprendre. Le déballage, avec des déclarations et des dits, pourrait être nouveau pour lui, alors je suis allé avec les améliorations les plus évidentes venant du code qu'il avait déjà écrit. – deontologician

1

Cela devrait fonctionner:

def read_one_file(): 
    f = open('C:\Python27\inventory.dat', 'r') 
    invid = f.readline() 
    stock = f.readline() 
    published = f.readline() 
    price = f.readline() 
    invtype = f.readline() 
    title = f.readline() 
    author = f.readline() 
    return invid, stock, published, price, invtype, title, author 

invid, stock, published, price, invtype, title, author = read_one_file() 

print "Update Number In Stock" 
print "----------------------" 
print "Item ID: ", invid 

Fondamentalement, vous retournez ce qu'on appelle un « tuple » des variables de la fonction et de l'affecter à un « tuple » des variables dans le programme principal. Le fait qu'ils portent le même nom n'est pas vraiment important pour le programme.

+0

Donc les retourner comme un tuple d'accord? Ou devrais-je créer un tableau (liste en python?). – Nogg

+0

Il n'y a rien de mal à les retourner en tant que tuple. – mattbornski

+0

Très bien, mais comment les imprimer plus tard? Je ne sais pas Si je pose la bonne question ... comment peut-on scinder le tuple, je suppose, pour pouvoir l'utiliser de façon indépendante. EDIT: Je viens de l'avoir. Je peux mettre invid = read_one_file – Nogg

1

Une autre option est de passer un dictionnaire dans l'appel de fonction, puis accéder aux variables du dict:

read_file_dict = {} 

def read_one_file(some_dict): 
    ... 
    some_dict['invid'] = file.readline() 
    some_dict['stock'] = file.readline() 
    ... 

Exécutez la fonction:

read_one_file(read_file_dict) 

Et puis accéder aux variables (dict entrées):

read_file_dict['invid'] 
4

Ceci est un peu plus propre pour ce que vous semblez essayer de faire. Note Je suppose que votre fichier inventory.dat n'est pas vraiment énorme, et a au moins 7 lignes.

def read_one_file(fname=r'C:\Python27\inventory.dat'): 
    with open(fname) as f: 
    spam = [line.strip() for line in f.readlines()] 
    keys = ['invid', 'stock', 'published', 'price', 'invtype', 'title', 'author'] 
    inventory_item = dict(zip(keys, spam[:len(keys)])) 
    return inventory_item 

d = read_one_file() 

print "Update Number In Stock" 
print "----------------------" 
print "Item ID: ", d['invid'] 

Répartition des modifications de votre code d'origine:

  • fname passé comme argument par défaut, plutôt que hardcoded dans la fonction
  • fname chaîne transformé en un r'raw string' avec le préfixe r, ce qui empêcherait les erreurs d'antislash d'être manipulées à tort (image par exemple si votre nom de fichier était ninventory.dat, avec le \ en tant que séparateur de chemin dans Windows, vous obtiendriez une nouvelle ligne dans le nom de fichier si vous utilisiez une chaîne normale)
  • fichier ouvert avec le gestionnaire de contexte, pour s'assurer qu'il est correctement fermé. google sur python avec statemen pour plus de détails.
  • [line.strip() for line in f.readlines()] est une liste de compréhension pour supprimer les nouvelles lignes de fin de vos données et stocker les lignes dans une liste appelée spam.
  • liste des clés définies, puis les n premières lignes du fichier sont mappées en tant que valeurs des clés, à l'aide d'un python dict.
  • spam[:len(keys)] découpe la liste en n premiers éléments, où n est le nombre de clés déclaré ci-dessus.
  • zip correspond juste à 2 itérations (dans ce cas les clés et les valeurs du fichier) dans un itérable de tuples, ce qui est l'une des formes acceptées lors de la création d'un nouveau dict.
  • d = read_one_file() stocke le résultat du fichier lu dans une variable. dans votre code, cela était perdu car il n'y avait pas de référence à la valeur de retour de la fonction détenue.
  • d['invid'] accède à la valeur de la clé 'invid' stockée dans le dict d. vous devriez accéder aux autres valeurs de la même manière.
+1

Cela vous dérangerait-il de le faire? C'est assez difficile à déchiffrer pour un novice. – Nogg

+0

OK, je vais modifier ma réponse avec une ventilation. – wim

0

La réponse courte: Comme d'autres l'ont dit, vous devez décompresser le tuple vous retournez, et les valeurs seront à votre disposition:

invid, stock, published, price, invtype, title, author = read_one_file() 

La longue réponse: Cela pourrait être un peu long, mais supporter avec moi, car c'est une information importante pour comprendre comment fonctionnent les différents langages de programmation. Le problème que vous rencontrez est une compréhension de la portée, la durée de vie des variables dans certaines portées, et comment les variables peuvent être transférées entre deux portées différentes. Je ferai de mon mieux pour aborder chacun d'entre eux, et comment cela se rapporte à votre problème.

Scope est essentiellement une section de votre programme dans laquelle certaines variables que vous déclarez existeront. Lorsque vous avez défini la fonction:

def read_one_file(): 
     f = open('C:\Python27\inventory.dat', 'r') 
     invid = f.readline() 
     stock = f.readline() 
     published = f.readline() 
     price = f.readline() 
     invtype = f.readline() 
     title = f.readline() 
     author = f.readline() 
     return invid, stock, published, price, invtype, title, author 

vous avez défini la portée. Les variables invid, stock, published, price, invtype, title et author existent dans cette fonction et cessent d'exister une fois cette fonction terminée. Python s'avère être un très bon visualiseur de portée, puisqu'il dépend de l'espace/des tabulations. Un nouveau niveau d'indentation définit une nouvelle étendue.

Afin d'obtenir une variable/valeur hors de la portée d'une fonction, vous pouvez le retourner, comme vous l'avez fait dans votre fonction. Mais la partie de votre programme qui appelle la fonction doit spécifier des variables dans sa propre portée qui recevront les valeurs renvoyées par la fonction.(Et pour recevoir les données, vous affectez la variable au résultat de la fonction: var = function())

Dans votre code posté, vous avez appelé read_one_file() mais n'a affecté aucune variable à ses valeurs renvoyées. Lorsque vous avez essayé d'accéder à l'une des valeurs que vous pensiez que vous reveniez:

print "Update Number In Stock" 
    print "----------------------" 
    print "Item ID: ", invid 

invid est pas techniquement une variable en dehors de read_one_file(), donc une erreur se produit. La clé est que les variables retournées ne les transfèrent pas automatiquement, par leur nom, à la portée de l'appelé (le code appelant la fonction). Vous devez spécifier une nouvelle variable dans l'appelé pour recevoir la valeur retournée.

Espérons que cela aide :)