2010-09-19 12 views
5

Estoy escribiendo un programa de Python con una GUI construida con el módulo Tkinter. Estoy usando una clase para definir la GUI porque hace que sea más fácil pasar comandos a los botones y hace que todo sea un poco más fácil de entender.¿Hay algún problema con un __init__ grande?

La inicialización real de mi GUI toma alrededor de 150 líneas de código. Para que esto sea más fácil de entender, he escrito la función __init__ así:

def __init__(self, root): 
    self.root = root 
    self._init_menu() 
    self._init_connectbar() 
    self._init_usertree() 
    self._init_remotetree() 
    self._init_bottom() 

donde _init_menu(), _init_connectbar(), y así sucesivamente hacer todo el trabajo de inicialización. Esto hace que mi código sea más fácil de seguir y evita que __init__ se vuelva demasiado grande.

Sin embargo, esto crea problemas de alcance. Dado que un widget de entrada que definí en _init_connectbar() está en el ámbito de la función y no es un atributo de clase, no puedo referirme a él en otros métodos de la clase.

Puedo hacer que estos problemas desaparezcan haciendo la mayor parte de la inicialización en __init__, pero perdería la abstracción que obtuve con mi primer método.

¿Debo expandir __init__, o encontrar otra forma de poner los widgets en el alcance de la clase?

Respuesta

1

¿Por qué no haces los widgets a los que debes referirte? Variables de instancia. Esto es lo que usualmente hago y parece ser un enfoque bastante común.

p. Ej.

self.some_widget 
+0

Supongo que podría definir cada widget en '__init__' y luego ejecutar métodos para hacer el real configuración y empaque de cada widget. –

+0

Eso no es exactamente lo que estaba sugiriendo. Aunque generalmente tengo un método diferente para hacer el diseño, aún puedes definir tus widgets en tus métodos '__init__widget()', pero crear las variables de instancia de widgets significa que puedes acceder a ellos en donde. – volting

1

Debería consultar el builder-pattern para este tipo de cosas. Si su GUI es compleja, habrá cierta complejidad al describirla. Si se trata de una función compleja o una descripción compleja en algún archivo se reduce a la misma. Simplemente puede intentar que sea lo más legible y fácil de mantener posible, y en mi experiencia, el patrón del constructor realmente ayuda aquí.

2

En mi opinión, debe almacenar los widgets como variables de instancia para que pueda consultarlos desde cualquier método. Como en la mayoría de los lenguajes de programación, la legibilidad disminuye cuando las funciones son demasiado grandes, por lo que su enfoque de dividir el código de inicialización es una buena idea.

Cuando la clase misma crece demasiado grande para un archivo fuente, también puede dividir la clase usando clases mix-in (similar a tener clases parciales en C#).

Por ejemplo:

class MainGuiClass(GuiMixin_FunctionalityA, GuiMixin_FunctionalityB): 
    def __init__(self): 
     GuiMixin_FunctionalityA.__init__(self) 
     GuiMixin_FunctionalityB.__init__(self) 

Esto es muy útil cuando la GUI se compone de diferentes funcionalidades (por ejemplo, una pestaña de configuración, una lengüeta de ejecución o en absoluto).

+0

Buena respuesta, pero estás siendo un poco demasiado prudente. La legibilidad disminuye para funciones grandes en _todos_ lenguajes de programación. –

+0

Wow. Debería haber visto que viene :) –

5

Guarde algunas de esas referencias de widgets en variables de instancia o devuélvalas (un conjunto mínimo de ideas; desea reducir el acoplamiento) y guárdelas en variables locales en __init__ antes de pasar las relevantes como argumentos a sus asistentes de construcción posteriores . Este último es más limpio, pero requiere que las cosas estén lo suficientemente desacopladas como para poder crear un orden que lo haga posible.

+0

Gracias, esto es lo que realmente debería estar haciendo.Supongo que haré que cada '_init_something' devuelva los widgets que inicializa. –

+0

@Rafe: solo los widgets "interesantes". Las GUI a menudo tienen otras cosas como etiquetas y marcos que no son interesantes; son como el conjunto en el que juegan los interesantes widgets (entradas, listboxes, lienzos, etc.). (Por supuesto, a veces las entradas no son realmente interesantes y las etiquetas sí, pero eso depende de los detalles de la GUI que estás construyendo ...) –

Cuestiones relacionadas