How to use oop with panda?

# To change this template, choose Tools | Templates
# and open the template in the editor.


from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import *

from direct.gui.OnscreenText import OnscreenText
from pandac.PandaModules import loadPrcFileData
from panda3d.core import Vec3
from direct.gui.OnscreenImage import OnscreenImage

class Application(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        self.dude = self.mainDude()
        
        
        class mainDude(object, self):
            
            def __init__(self):
                self.smiley = loader.loadModel("smiley")
                self.smiley.reparentTo(render)
                self.smiley.setPos(0,  0,  0)
            
            

But I get “application instance has no attribute mainDude”

First of all, why are you attempting to define the “mainDude” within the “init” method of Application, instead of outside of the Application class entirely? I gather that such a thing is possible in Python, but I’m not sure of what benefit it provides here…

Secondly, you seem to be defining “mainDude” after you attempt to use it: “self.dude = self.mainDude()” presumes that “mainDude” has been defined at that point, which I don’t believe that it has. If “mainDude” were a method of the class defined outside of the “init” method then this would likely work, but within the same method I suspect that the definition of “mainDude” simply hasn’t yet been reached.

How about this?

from direct.showbase.ShowBase import ShowBase

class SmileyApplication(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        self.dude = MainDude()
        self.dude.load()
        
        
class MainDude(object):
    def load(self):
        self.smiley = loader.loadModel("smiley")
        self.smiley.reparentTo(render)
        # position is 0,0,0 by default. no need to set it
        #self.smiley.setPos(0,  0,  0)    

This way you can also split your classes over multiple files.

Or, if you wan’t automatic load on creation of your MainDude:

from direct.showbase.ShowBase import ShowBase

class SmileyApplication(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        self.dude = MainDude()
        
        
class MainDude(object):
    def __init__(self):
        self.load()


    def load(self):
        self.smiley = loader.loadModel("smiley")
        self.smiley.reparentTo(render)
        # position is 0,0,0 by default. no need to set it
        #self.smiley.setPos(0,  0,  0)