2010-12-06 72 views
0

Je vais légèrement simplifier le code dans l'espoir que quelqu'un puisse faire la lumière sur ce sujet et peut-être me donner une approche plus pythonique si ce que je fais est faux.Pourquoi cette variable est-elle maintenant multi-module globale en python?

intérieur dbcontrollers.py

import autosettings 
import aerialcontroller 
import controller 
import gobject 
import gtk 
import utils 

# Create the settings object so we can call and edit settings easily 
SETTINGS = autosettings.autoSettings() 
CONTROLLERS = {} 

class dBControllers(object): 

    def __init__(self): 

     # This works happily so nothing wrong in autosettings module 
     print SETTING.last_port 
     port_to_use = SETTINGS.last_port 

if __name__ == "__main__": 

    # Create an object that holds all the GTK stuff (when not simplified) 
    dBControllers = dBControllers() 
    aerialController = aerialcontroller.aerialController() 

intérieur aerialcontroller.py

class aerialController(object): 

    def __init__(self): 

     self.motor_number = str(SETTINGS.aerial_motor_number) 
     CONTROLLERS[self.motor_number] = self 

Mais quand je lance, je reçois "NameError: nom global 'Paramètres' est pas défini".

Je ne comprends pas vraiment comment cela est supposé fonctionner, en partageant des variables globales entre modules. Je suppose que ce n'est pas la bonne façon de faire des choses comme ça, alors quelqu'un peut me diriger dans la bonne direction.

Merci.

P.S. De simples exemples de code seraient bénéfiques - encore un nouveau venu relatif à python.

+0

Inside "__init__. py "il y a une importation pour" aerialcontroller "... dans" aerialcontroller.py "il n'y a pas d'importations. Faut-il y en avoir un? Si oui, quoi? Comment importer "__init__.py" ?? – Schodemeiss

+0

Consultez http://docs.python.org/tutorial/modules.html#packages pour plus d'informations sur les fichiers __init__ – Raz

+0

J'ai renommé mon "__init__.py" en "dbcontrollers.py" pour peut-être simplifier le problème. Mais, jusqu'à présent, toujours pas de chance :( – Schodemeiss

Répondre

3

Python n'a aucun moyen de partager un nom entre les modules. Si vous souhaitez accéder à un élément à partir de plusieurs modules, déclarez-le dans un module distinct (par exemple, "paramètres"), puis importez-le où vous le souhaitez.

settings.py:

SETTINGS = autosettings.autoSettings() 
CONTROLLERS = {} 

aerialcontroller.py

from settings import SETTINGS, CONTROLLERS 
class aerialController(object): 

    def __init__(self): 
     self.motor_number = str(SETTINGS.aerial_motor_number) 
     CONTROLLERS[self.motor_number] = self 

N.B. Faire from settings import SETTINGS fonctionnera aussi longtemps que vous voulez seulement modifier PARAMETRES. Si vous souhaitez le remplacer complètement par un nouveau jeu de paramètres (SETTINGS = ...), vous devez effectuer les réglages d'importation et vous y référer en tant que settings.SETTINGS. Ceci est par nature: si les modules ont des variables du script qui les ont importés, il serait beaucoup plus difficile de voir d'où ils viennent en lisant le code (et importer le module de quelque part peut ne pas fonctionner). De cette façon, vous pouvez toujours voir d'où vient la variable à l'intérieur de chaque fichier (enfin, presque toujours: s'il vous plaît ne pas abuser from <name> import *).

1

Je pense que la façon la plus sensée est de rendre votre aerialController classe prendre un des paramètres et des contrôleurs objet:

class aerialController(object): 

    def __init__(self, settings, controllers): 
     self.motor_number = str(settings.aerial_motor_number) 
     controllers[self.motor_number] = self 

... puis, dans l'autre module:

if __name__ == "__main__": 
    dBControllers = dBControllers() 
    aerialController = aerialcontroller.aerialController(SETTINGS, CONTROLLERS) 

Vous pourriez probablement structurer cela encore mieux et avoir le numéro de moteur passé, et l'appelant faire l'attribution à la controllers, mais c'est hors sujet ...

+0

En fait, je pense que la dernière chose que vous mentionnez (l'ajouter à CONTROLLERS où il est instancié) est probablement une bonne idée. Cependant, je ne souhaite pas passer les paramètres en argument au constructeur. –

+0

@Thomas K - il n'y a pas de grande différence entre le passer dans le constructeur et importer depuis un module - de toute façon, il est dans un espace de noms accessible (local vs global) et peut être muté à partir de là. Bien sûr, s'il n'utilise que le membre 'aerial_motor_number', c'est tout ce dont vous avez besoin. – detly

+0

Ils sont fonctionnellement identiques, mais conceptuellement, il est préférable d'avoir un module partagé plutôt que de passer un objet. Cependant, je n'ai pas de problème avec la simple transmission d'une valeur. 'CONTROLLERS [aerial_motor_number] = aerialcontroller.aerialController (aerial_motor_number)' –