0

j'ai commencé Libre-Office Calc avec la commande suivante:Python 3 retourne classe null lorsque vous utilisez contructor

$ libreoffice --calc --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager" 

import uno 

# Class so I don't have to do this crap over and over again... 
class UnoStruct(): 
    localContext = None 
    resolver = None 
    ctx = None 
    smgr = None 
    desktop = None 
    model = None 
    def __init__(self): 
     print("BEGIN: constructor") 
     # get the uno component context from the PyUNO runtime 
     localContext = uno.getComponentContext() 

     # create the UnoUrlResolver 
     resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext) 

     # connect to the running office 
     ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") 
     smgr = ctx.ServiceManager 

     # get the central desktop object 
     desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx) 

     # access the current writer document 
     model = desktop.getCurrentComponent() 

     print("END: constructor") 

Et puis je l'appelle avec:

myUno = UnoStruct() 
BEGIN: constructor 
END: constructor 

et tenter de l'obtenir avec

active_sheet = myUno.model.CurrentController.ActiveSheet 

AttributeError: 'NoneType' object has no attribute 'CurrentController' 

et il apparaît que le model est None (null)

>>> active_sheet = myUno.model 
>>> print(myUno.model) 
None 
>>> print(myUno) 
<__main__.UnoStruct object at 0x7faea8e06748> 

Alors, que s'est-il passé dans le constructeur? Ne devrait-il pas encore être là? J'essaie d'éviter le code de la plaque de la chaudière.

+0

P.S. Je suis conscient que ce n'est pas vraiment une structure, je l'ai juste appelé ça. – leeand00

+0

Vous ne définissez jamais 'myUno.model', donc c'est toujours' None' de la définition de la classe. – kindall

+0

La classe 'UnoObjs' de [ce code github] (https://github.com/silnrsi/libreoffice-linguistic-tools/blob/master/LinguisticTools/pythonpath/lingt/utils/util.py) le fait. –

Répondre

2

Je voudrais ajouter à la réponse de Barros que vous déclarez localContext = None, resolver = None, etc. comme variables de classe. Donc le code modifié est ceci (si vous avez besoin de toutes ces variables comme variables d'instance):

class UnoStruct(): 
    def __init__(self): 
     # get the uno component context from the PyUNO runtime 
     self.localContext = uno.getComponentContext() 

     # create the UnoUrlResolver 
     self.resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext) 

     # connect to the running office 
     self.ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") 
     self.smgr = ctx.ServiceManager 

     # get the central desktop object 
     self.desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx) 

     # access the current writer document 
     self.model = desktop.getCurrentComponent() 
+0

Alors 'self' est comme' this' dans Java alors? – leeand00

+1

@ leeand00 Oui. La différence est que 'self' n'est pas un mot-clé (juste un nom conventionnel): vous pouvez le remplacer par' obj', 'this', peu importe, puisque le paramètre est explicite (ceci est assez commun pour les langages qui n'ont pas été conçus orienté objet initialement). –

+0

juste, parce que c'est un argument, donc vous pouvez le nommer vous-même. Mais si vous voulez un autre codeur Python pour le lire facilement, il vaut mieux s'en tenir à la convention 'self'. – leeand00

2

Vous devez être explicit:

self.model = desktop.getCurrentComponent() 

La variable model à l'intérieur __init__ est locale à cette méthode, et ne sera pas attaché à l'instance self à moins que vous lui attribuez.

Lorsque vous avez défini model juste sous la classe, mais en dehors de la méthode __init__ que vous avez défini un class attribute, qui sera dans tous les cas de cette catégorie. Sans cela, lorsque vous accéderez à myUno.model, vous serez confronté à AttributeError.