[Python] Brincando com GObjects
Posted 12-11-2009 at 14:26 by Magnun
Atenção!!! Isso não faz parte do curso de python!!
Antes de começar que explicar que esse post não tem nenhuma relação direta com o Curso de Python que eu tenho postado aqui na Under-Linux. Eu não recomendo a leitura desse post para os iniciantes em Python. Como esse post terá uma alta dose de conteúdos intermediários isso pode fazer com que vocês desistam de Python
. Explicado isso vamos ao assunto...Sempre que desenvolvo um projeto gosto de fazer a modelagem dos dados mas básicos utilizando GObjects. Tudo isso por causa do sinais, chamados de gsignals, que o GObject proporciona! Eles realmente ajudam a simplificar o código e automatizar tarefas. Em caso de um projeto ainda em desenvolvimento o uso de gsignals é ideal pois facilita o refatoramento do código ao não atrelar metodos a de uma classe X a outros de uma classe Y. Complicou?? Eu explico! Mas a melhor forma de explicar isso é através de um exemplo...
Para tudo fazer mais sentido, vamos fazer rapidamente um programa de controle de estoque simplificado. Algumas tarefas dele (como armazenamento de dados) ficaram subjetivas pois não vou entrar nesse mérito, o foco aqui é GObjects e gsignals!!
Primeiro vamos modelar o controle de estoque...
Código:
#!/usr/bin/env python
#-*- coding: iso8859-1 -*-
class Item:
def __init__(self, nome, quantidade=0):
self.nome = nome
self.quantidade = quantidade
def vende(self, quantidade):
self.quantidade -= quantidade
def comrpa(self, quantidade):
self.quantidade += quantidade
class Estoque:
def __init__(self):
self.itens = []
def novo_item(self, item):
self.itens.append(item)
def mostra(self):
print 'Situacao atual do estoque...'
for item in self.itens:
print ' ', item.nome.ljust(20, '.'),item.quantidade
print
def fecha_DB(self):
print 'fechando o bando de dados'
print
def abre_DB(self):
print 'abrindo o bando de dados'
print
self.itens.append(Item('Legiao Urbana', 20))
self.itens.append(Item('Guns n Roses', 5))
self.itens.append(Item('Rush', 3))
self.itens.append(Item('Iron Maiden', 12))
self.itens.append(Item('Pantera', 7))
def adiciona_DB(self, item):
print 'adicionando o item', item.nome, 'ao banco de dados'
if __name__ == '__main__':
estoque = Estoque()
estoque.abre_DB()
estoque.mostra()
estoque.novo_item(Item('Counting Crows', 1))
estoque.mostra()
estoque.itens[0].vende(3)
estoque.mostra()
Código:
abrindo o bando de dados Situacao atual do estoque... Legiao Urbana....... 20 Guns n Roses........ 5 Rush................ 3 Iron Maiden......... 12 Pantera............. 7 Situacao atual do estoque... Legiao Urbana....... 20 Guns n Roses........ 5 Rush................ 3 Iron Maiden......... 12 Pantera............. 7 Counting Crows...... 1 Situacao atual do estoque... Legiao Urbana....... 17 Guns n Roses........ 5 Rush................ 3 Iron Maiden......... 12 Pantera............. 7 Counting Crows...... 1
Método 1 - Gambiarra?!
Uma é passar para cada instância de Item um ponteiro para a instância de Estoque e adicionar chamadas para os métodos. Esse método tem certas falhas:
- À medida que seu programa cresce esse número de ponteiros também cresce;
- Se um dia você quiser mudar o nome do método vai ter que procurar todas as vezes que ele foi referenciado;
- O número de chamadas à métodos pode crescer vertiginosamente dependendo do tamanho do seu programa;
- Cada nova classe vai ter que ser referânciado dentro de todas as outras classes;
- Muitas vezes ocorrem referências cruzadas.
Método 2 - GObjects e GSingnals
O método mais escalável e limpo é utilizar GObjects e GSignals. Para isso primeiro todas as nossas classes vão ter que ser sub-classes do GObjects. Para isso vamos alterá-las da seguinte forma:
Código:
import gobject
class Item(gobject.GObject):
__gsignals__ = {
'item-vendido' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
'item-comprado' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
}
def __init__(self, nome, quantidade=0):
gobject.GObject.__init__(self)
- Uma Flag que, entre outras coisas, especifica o estágio em que o sinal será emitido (não precisa se preocupar muito com isso) - mais informações aqui.
- O tipo da variável de retorno, que nesse caso é None;
- E os argumentos, que nesse caso estão vazios.
Código:
#!/usr/bin/env python
#-*- coding: iso8859-1 -*-
import gobject
class Item(gobject.GObject):
__gsignals__ = {
'item-vendido' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
'item-comprado' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
}
def __init__(self, nome, quantidade=0):
gobject.GObject.__init__(self)
self.nome = nome
self.quantidade = quantidade
def vende(self, quantidade):
self.quantidade -= quantidade
self.emit('item-vendido')
def compra(self, quantidade):
self.quantidade += quantidade
self.emit('item-comprado')
class Estoque:
def __init__(self):
self.itens = []
def novo_item(self, item):
self.itens.append(item)
item.connect('item-vendido', self.ao_comprar_item)
item.connect('item-comprado', self.ao_vender_item)
def mostra(self):
print 'Situacao atual do estoque...'
for item in self.itens:
print ' ', item.nome.ljust(20, '.'),item.quantidade
print
def fecha_DB(self):
print 'fechando o bando de dados'
print
def abre_DB(self):
print 'abrindo o bando de dados'
print
self.novo_item(Item('Legiao Urbana', 20))
self.novo_item(Item('Guns n Roses', 5))
self.novo_item(Item('Rush', 3))
self.novo_item(Item('Iron Maiden', 12))
self.novo_item(Item('Pantera', 7))
def adiciona_DB(self, item):
print 'adicionando o item', item.nome, 'ao banco de dados'
def ao_comprar_item(self, item):
print 'Item vendido:',item.nome
print
self.mostra()
def ao_vender_item(self, item):
print 'item comprado:',item.nome
print
self.mostra()
if __name__ == '__main__':
estoque = Estoque()
estoque.abre_DB()
estoque.novo_item(Item('Counting Crows', 1))
estoque.itens[0].vende(3)
estoque.itens[1].vende(1)
estoque.itens[2].compra(10)
Código:
$ python teste.py abrindo o bando de dados Item vendido: Legiao Urbana Situacao atual do estoque... Legiao Urbana....... 17 Guns n Roses........ 5 Rush................ 3 Iron Maiden......... 12 Pantera............. 7 Counting Crows...... 1 Item vendido: Guns n Roses Situacao atual do estoque... Legiao Urbana....... 17 Guns n Roses........ 4 Rush................ 3 Iron Maiden......... 12 Pantera............. 7 Counting Crows...... 1 item comprado: Rush Situacao atual do estoque... Legiao Urbana....... 17 Guns n Roses........ 4 Rush................ 13 Iron Maiden......... 12 Pantera............. 7 Counting Crows...... 1
Magnun Leno
CISCO CCNA: CSCO10991731
e-mail: magnunΘunder-linux.org
Blog: root@blog:/# chmod o+r *
Participe de uma comunidade!
"If you choose not to decide, you still have made a choice."
- Freewill (Rush)
CISCO CCNA: CSCO10991731
e-mail: magnunΘunder-linux.org
Blog: root@blog:/# chmod o+r *
Participe de uma comunidade!
"If you choose not to decide, you still have made a choice."
- Freewill (Rush)
Total Comments 0
Comentários
Enviar um comentario
|

![Submit "[Python] Brincando com GObjects" to Digg](images/misc/bookmarksite_digg.gif)
![Submit "[Python] Brincando com GObjects" to del.icio.us](images/misc/bookmarksite_delicious.gif)
![Submit "[Python] Brincando com GObjects" to StumbleUpon](images/misc/bookmarksite_stumbleupon.gif)
![Submit "[Python] Brincando com GObjects" to Google](images/misc/bookmarksite_google.gif)




