Is there a difference between self.loader and loader?

All of my code is in my MyGame class, in my class to load my models I do self.loader.loadModel(), I realized that when I removed the self from it, it still worked. I wanted to know if there is any difference when I do this or not.

The answer to that is perhaps both “yes” and “no”.

Let me explain:

The “loader” object is a thing provided by ShowBase. I presume that your “MyGame” class inherits from ShowBase, and thus inherits access to “loader”–hence “self.loader” working.

However, ShowBase also provides global access to certain variables–amongst them “loader”. This means that one should be able to access “loader” from just about anywhere–hence “loader” working.

But there’s a caveat: this global-variable approach is, I believe, now deprecated. While it still works, it may be removed in the future, and is not the recommended approach any more.

So, there’s no difference in that they’re both the same object, but there is a difference in that one of them is no longer recommended.

1 Like

In more simple forms:

self.loader or base.loader are both referring to a ShowBase objects loader

and

loader is a global variable that you can use without accessing objects.

But like @Thaumaturge said, the latter isn’t recommended anymore as it is deprecated, and it will be hard for users new to panda and python to understand where the variable was defined, which spoils their learning.

1 Like

oh ok, so would it be fine to do base.loader as well as base.render when I am trying to load models and reparent them outside of my mygame class? For example, I created a player class that has all my attributes for my player, and I’ve been using base.loader in there, do you recommend that or should I go about it a different way?

Yes, what you say is correct. Don’t use things like render, loader and run without the self or base prefix as they are deprecated. Also, to avoid confusion for other programmers, set base as a global variable as an instance of ShowBase at the top of the file after the imports like:

base = ShowBase()

class Player(DirectObject):
    pass

This is just showing others the value of base, even though it is already defined.

1 Like

On the contrary, I don’t recommend doing that: the code there is creating a new, separate instance of ShowBase in your player-class file, I believe, which may have unintended side-effects.

(It’s not clear to me why the Player class inherits from DirectObject–but if you want said class to use some of the functionality of DirectObject, such as accepting its own events separate from ShowBase, then fair enough.)

No and yes: My understanding is that the use of the global variable “base” is as deprecated as any of the other global variables, like “render” or “loader”. (The “base” variable being just a global variable that references the current instance of ShowBase.)

So “yes”, in that it should work, but “no” in that it’s also deprecated, if I’m not much mistaken.

Instead, what I believe is recommended these days is to create a “common” Python-file that holds references to things like the ShowBase instance, as well as any other objects or values that you want to have be globally accessible. This can then be imported by any files that require such access.

Like this:

The “common” script–let’s say that it’s in a file called “Common.py”:

myGameObj = None

In your main program-script:

# The usual importations here, omitted for brevity and clarity

import Common

class MyGame(ShowBase):
    def __init__(self):
        # The usual initialisation here, omitted for brevity and clarity

        # Now, set the relevant variable in the "common" file
        # to hold a reference to this object, for others to access
        Common.myGameObj = self

        # The rest of the program follows as usual

And then, in some other file that might want to access the game-object, such as to use “loader”:

# The file's usual importations here, again omitted for brevity and clarity

import Common

class SomeClass():
    def __init__(self):
        # The usual construction here, omitted for brevity and clarity

        self.model = Common.myGameObj.loader.loadModel(someModelPath)
1 Like

I’ve added this into my program, thank you.

1 Like