Skip to main content
gamedev.net
🔒 Locked

Python Organization

Started by CyberSlag5k Mar 1, 2009 at 8:49 PM 16 replies 2k views
Original Post
CyberSlag5k
CyberSlag5k
I'm beginning my first serious Python project, and I'm wondering how I can best organize it. In a Cxx project, I would set up a main game loop which would update objects defined in various other classes. I'd like to do something similar in my Python project, but I'm not sure how a partial class would work, as well as how best to handle all the various imports. This is what I have right now: main.py:

import direct.directbase.DirectStart #Panda3D library

import globals
import setup
import input
import camera

run() #comes from Panda

globals.py:

cameraX = 0.0
cameraY = 0.0

setup.py:

environment = loader.loadModel("models/environment")
environment.reparentTo(render)
environment.setScale(0.25, 0.25, 0.25)
environment.setPos(-8, 42, 0)

camera.py:

from globals import cameraX, cameraY
from direct.task import Task
from direct.actor import Actor
import math

def SpinCameraTask(task):
	angledegrees = task.time * 6.0
	angleradians = angledegrees * (math.pi / 180.0)
	base.camera.setPos(20 * math.sin(angleradians), -20*0 * math.cos(angleradians), 3)
	base.camera.setHpr(cameraX, cameraY, -20)
	return Task.cont
	
taskMgr.add(SpinCameraTask, "SpinCameraTask")

input.py not yet defined. These are the questions I have: 1. Is the above a sensible organization scheme for my project? Am I maybe adhering too much to my C style background? 2. I think I may have to do all of this stuff within a derived class (to take advantage of inherited non-static functions). How can I span this class across the multiple files? Is doing a class MyClass(MyParent): at the top of each page equivalent to doing a partial method, like in C#? 3. How on Earth do you keep things straight? I mean, look at main.py. I'm calling a function called run(), which I know comes from the panda library, but just looking at my code there, you'd have no idea where it came from. Or myabe you would, and if so, how? All of these examples I'm looking at online are so ambiguous. Coupled with a lack of variable and signature information tools in the IDE (like what parameters a method is expecting), I'm finding myself have trouble keeping everything straight. The examples for the library I'm using don't seem to mind this, either. They just call stuff, like self.accept(), for example, without bothering to tell you what self is or what accept might do or be coming from. It's all very confusing. Can anyone suggest some techniques to reconcile these problems? I recall, from my Python days of old, a way to use the interpreter to at least get some of the definitions for things. That would be a good start.
Without order nothing can exist - without chaos nothing can evolve.
Oluseyi
Oluseyi
Quote:
Original post by CyberSlag5k
1. Is the above a sensible organization scheme for my project?

No. You have too many unnecessary files. globals.py and setup.py are useless. Python's import is NOT C's #include.

Quote:
Am I maybe adhering too much to my C style background?

Definitely.

Quote:
2. I think I may have to do all of this stuff within a derived class (to take advantage of inherited non-static functions). How can I span this class across the multiple files? Is doing a class MyClass(MyParent): at the top of each page equivalent to doing a partial method, like in C#?

Why do you think you need a partial class? First of all, your code is entirely devoid of object-oriented behaviors, which is not to say that object orientation is necessary, but Python is an extremely object-aware languages - even intrinsic values like strings are objects and have accessible methods.

The common approach is to write classes that are abstractions in your various modules, and then in your main file import the modules and use the classes within them to define your application/solution.

Quote:
3. How on Earth do you keep things straight? I mean, look at main.py. I'm calling a function called run(), which I know comes from the panda library, but just looking at my code there, you'd have no idea where it came from. Or myabe you would, and if so, how?

Normally, when you import a module it introduces the entire module as a nested namespace. If the function run() exists in the DirectStart nested module from Panda3D, you should normally have to refer to it as DirectStart.run(). However, Panda3D explicitly inserts several symbols into the global namespace, which is why run() is available. See here for more information.

Quote:
All of these examples I'm looking at online are so ambiguous. Coupled with a lack of variable and signature information tools in the IDE (like what parameters a method is expecting), I'm finding myself have trouble keeping everything straight.

You need more Python aware tools. Properly documented Python module functions include a docstring that describes their interface, and good Python tools can read that data and construct code completion and parameter hints from it. There's nothing you can do if the function isn't well documented, though. For that, you'll just have to keep referring to the documentation.

Quote:
The examples for the library I'm using don't seem to mind this, either. They just call stuff, like self.accept(), for example, without bothering to tell you what self is or what accept might do or be coming from.

In Python instance methods explicitly accept the object reference as their first parameter. By convention, that parameter is called self. If you're trying to program in Python, you should know this - which suggests that you haven't bothered to learn the language first, or have forgotten much of it, which explains your confusion.

Quote:
I recall, from my Python days of old, a way to use the interpreter to at least get some of the definitions for things. That would be a good start.

help(function)
Fruny
Fruny
Quote:
Original post by Oluseyi
help(function)


help and dir are both your friends.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
CyberSlag5k
CyberSlag5k
Quote:

The common approach is to write classes that are abstractions in your various modules, and then in your main file import the modules and use the classes within them to define your application/solution.


That's exactly what I'm looking for. If I follow, this is exactly what I'd do in a C++/# program as well. I was attempting to do this, ironically, without the classes, as I thought I was meant to. I know Python is Object Oriented, but thus far is has a more in-line, functional feel to it, which I know is not right. It seemed like I should be constructing the pieces of a big global namespace across my files.

Quote:

Why do you think you need a partial class?


I thought that that accept function was on Panda's DirectObject function. They example on keyboard input refers to it, and as I couldn't tell where it was coming from, I opened up one of their examples, and saw self being used in a class that inherited from DirectObject, so I figured my big global class needed to inherit from that.

Quote:


Normally, when you import a module it introduces the entire module as a nested namespace. If the function run() exists in the DirectStart nested module from Panda3D, you should normally have to refer to it as DirectStart.run(). However, Panda3D explicitly inserts several symbols into the global namespace, which is why run() is available. See here for more information.


That's comforting to know. Doing a bit of digging, it seems like __builtin__ is an object defined in some other module, imported and expanded in DirectBase, which is created by DirectShow, which I have imported in my main file. Is that correct?

Quote:

You need more Python aware tools. Properly documented Python module functions include a docstring that describes their interface, and good Python tools can read that data and construct code completion and parameter hints from it.


What do you recommend? I've just been using NotePad++.

Quote:
If you're trying to program in Python, you should know this - which suggests that you haven't bothered to learn the language first, or have forgotten much of it, which explains your confusion.


I was hoping to learn as I go. I'm very much a hands-on learner. That said, it's obvious that I need some supplemental reading. I'd just been using Dive Into Python to fill in the gaps as I get stuck. I'll read through some of the documents on the Python.org site before I dive back in. Are there any particularly good resources you'd recommend? I tend to do better with more tactile resources, rather than more dry documentation, if that makes sense. I'd tried to find something akin to Effective C++, which I was able to read and understand very quickly, for Python, but I didn't come across much.

Quote:

help and dir are both your friends.


Those will come in handy. I see now there's also a Type, as well.

Thank you both for your response. This has been very helpful.
Without order nothing can exist - without chaos nothing can evolve.
Fruny
Fruny
I tend to just use IDLE, or even plain nano.

For larger projects, I use the Komodo IDE. If you don't have money to spend on it, SPE (Stani's Python Editor) is a fair choice. Komodo Edit, the free version of ActiveState's IDE is OK ... as an editor. It obviously lacks the whole interpreter and debugger integration of the full version, so I cannot really recommend it.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Oluseyi
Oluseyi
Quote:
Original post by CyberSlag5k
That's exactly what I'm looking for. If I follow, this is exactly what I'd do in a C++/# program as well. I was attempting to do this, ironically, without the classes, as I thought I was meant to. I know Python is Object Oriented, but thus far is has a more in-line, functional feel to it, which I know is not right. It seemed like I should be constructing the pieces of a big global namespace across my files.

Python is multi-paradigm. Objects are truly first-class, but there is no imposition of programming paradigm. You can write procedural, object-oriented, functional and generic code quite easily, giving you the freedom to choose the best fit approach for your problem.

Python does not allow you to construct explicit namespaces. They are implicit in the declarations of classes and modules. It also does not support partial classes, so your namespaces must effectively be declared in one shot. The exception is packages, which may correspond to the filesystem: if you have a module X corresponding to a directory X, all files in that directory comprise elements of the namespace and you can direct the explicit construction of that namespace and turn the module into a package by creating a file named __init__.py. Read more here.

Quote:
I thought that that accept function was on Panda's DirectObject function. They example on keyboard input refers to it, and as I couldn't tell where it was coming from, I opened up one of their examples, and saw self being used in a class that inherited from DirectObject, so I figured my big global class needed to inherit from that.

Directobject.accept is undocumented. Keep in mind that method dispatch in Python is generic - that is, it is entirely type agnostic. If you have two variables a and b holding references to instances of two unrelated types, classA and classB, both of which implement a method exec, it is perfectly valid to do:
for o in [a, b]:    o.exec()

Several things happen here:
  1. the temporary list object is constructed from elements of different types - Python collections are not just generic, but type agnostic;

  2. the temporary iteration variable o is rebound to objects of different types - Python variables do not have type, and merely hold references to objects (which can not be coerced from one type to another, ie there is no casting in Python);

  3. the method exec is dispatched against the actual objects referred to by o at runtime, with no check to see if their class types contain such a method - if one doesn't exist, an AttributeError exception is generated at runtime;

  4. Python has no requirement that all instances of a class be structurally identical - you can add members/methods to individual instances at any time - so the attribute access for method dispatch doesn't actually check the class, but rather the object's attribute dictionary which is initially composed at creation from the explicit type and list of parent types.

In other words, the method accept may have been introduced at any stage in the lifetime of the instance self prior to its successful dispatch.

Post a link to the example that's confusing you, and maybe we can help.

Quote:
That's comforting to know. Doing a bit of digging, it seems like __builtin__ is an object defined in some other module, imported and expanded in DirectBase, which is created by DirectShow, which I have imported in my main file. Is that correct?

Yes. __builtins__ is built in: it is a dictionary created by the Python interpreter which holds all the built in functions. Fire up your Python interactive session and type dir(). Then type dir(__builtins__). The first, which should return four strings in a list, is the contents of the global/default namespace. The second is the contents of the __builtins__ dictionary, which the Python interpreter searches for global-level symbol resolution after searching any runtime created symbols inserted into the global namespace. To illustrate, define a simple function and then execute dir(). You'll see that your function's name has been added to the global namespace. Read more here.

Quote:
What do you recommend? I've just been using NotePad++.

I use ActiveState Komodo. It's not cheap, though - about $300. However, I justify the cost on the basis of its excellent Python support and the fact that it is a multi-language IDE, with a particular emphasis on dynamic languages - JavaScript, PHP, Perl, Ruby, etc.

Quote:
I was hoping to learn as I go. I'm very much a hands-on learner. That said, it's obvious that I need some supplemental reading. I'd just been using Dive Into Python to fill in the gaps as I get stuck. I'll read through some of the documents on the Python.org site before I dive back in.

Learning as you go is fine, but you're jumping ahead of your learning in terms of the ambition of the code you're trying to write. Without a decent grasp of Python, something like Panda3D will be very confusing. Perhaps you want to start with something simpler, like PyGame, and then move up as you become more comfortable with the language?

Quote:
Are there any particularly good resources you'd recommend?

Python for Software Design, the follow up to How to Think Like a Computer Scientist: Learning with Python. You might find it to be a bit of "dry documentation," but a collection of performance/correctness/expressiveness tips doesn't help until you have a sound fundamental grounding - reading Effective C++ without understanding basic C++ does you no good.
CyberSlag5k
CyberSlag5k
I've got IDLE installed, but I'm not overly fond of it. I watched a tutorial on some of SPE's features, and it looks pretty nice, so I'll give that a shot. Thanks, Fruny!

Quote:

In other words, the method accept may have been introduced at any stage in the lifetime of the instance self prior to its successful dispatch.


I think that's been causing a lot of my confusion, the fact that these things can come in at any time.

Quote:

Post a link to the example that's confusing you, and maybe we can help.


This was what was confusing me. I inferred that self referred to a DirectObject derivative because I opened up the Panda Asteroids sample and saw that the call was made within a class that inherited from it.

Quote:

Learning as you go is fine, but you're jumping ahead of your learning in terms of the ambition of the code you're trying to write. Without a decent grasp of Python, something like Panda3D will be very confusing. Perhaps you want to start with something simpler, like PyGame, and then move up as you become more comfortable with the language?


Yes, I think you're right. I'll take a look at PyGame. The project I had planned for Panda3D can be done just as well in 2D, so the transition to and from Panda and Python should be easy. The funny thing is, though, that I originally got into Panda3D as I was looking to start a new C++ project, since I had been pampered by C# for a few years, and wanted to get back into C++. I switched to Python to to ease my time in Panda (as I like what I've seen of the engine). Further and further down the rabbit hole I go (though the poor rabbit was eaten by a python weeks ago).

Quote:

Python for Software Design, the follow up to How to Think Like a Computer Scientist: Learning with Python.


I'm a little confused. Is Learning with Python the earlier version of the same book? Their website suggests it is. Is it enough to just read Python for Software Design, or would it be helpful to read its predecessor first?

Quote:

You might find it to be a bit of "dry documentation," but a collection of performance/correctness/expressiveness tips doesn't help until you have a sound fundamental grounding - reading Effective C++ without understanding basic C++ does you no good.


Yeah, I'd considered what it would be like reading Effective C++ when new to C++. I guess it's the style that I really liked, but while I could say I knew C++ before reading it, it was only after I read it that I felt I could say I really owned it. Still, I'd been using the language for years before I read it, so I suppose it would be a bit presumptive to think I could learn as much from a python book at this point in my python journey.

Thank you very much for all of your help, and for your sharing your rather impressive (some might say scary) level of knowledge, Oluseyi.

Oh, and it sounds like you've worked with Panda before. What have you done with it? Are you a contributor to the project?
Without order nothing can exist - without chaos nothing can evolve.
Fruny
Fruny
First of all, I'll just say that I agree with everything Oluseyi has said so far. Now that this is out of the way...

Quote:
Original post by CyberSlag5k
I think that's been causing a lot of my confusion, the fact that these things can come in at any time.

In most usual cases, they don't. They get set up in __init__ and don't really really come and go after that. Just because you can do it doesn't mean you have to do it. The option is just there, should it make sense one day for you to use it.

Quote:
I inferred that self referred to a DirectObject derivative because I opened up the Panda Asteroids sample and saw that the call was made within a class that inherited from it.

As Oluseyi pointed out before, the self argument is always explicitly passed to methods, unlike C++'s implicit this. It refers to the object itself ([caution] there are variations, much like there is a lot more to type than you might think, but you need not worry about them right now).

Quote:

Perhaps you want to start with something simpler, like PyGame, and then move up as you become more comfortable with the language?


I second that. Tinker with something simple until you got the hang of the language, its idioms, constructs and most often used library modules.

Quote:
I switched to Python to to ease my time in Panda (as I like what I've seen of the engine). Further and further down the rabbit hole I go (though the poor rabbit was eaten by a python weeks ago).

Some years ago, Washu suggested I have a look at Python one evening I was bored. That was before the Christmas holidays... when school resumed, I was hooked.


Quote:
Is Learning with Python the earlier version of the same book? Their website suggests it is. Is it enough to just read Python for Software Design, or would it be helpful to read its predecessor first?


Looks like it is. The text for both books is available online, so it should be easy enough to compare.

Quote:

Yeah, I'd considered what it would be like reading Effective C++ when new to C++. I guess it's the style that I really liked, but while I could say I knew C++ before reading it, it was only after I read it that I felt I could say I really owned it. Still, I'd been using the language for years before I read it, so I suppose it would be a bit presumptive to think I could learn as much from a python book at this point in my python journey.


You should have a look at "C++ Coding Standards" by Sutter and Alexandrescu, as well as "C++ Common Knowledge", by Dewhurst.

As far as Python goes, I learned with "Python in a Nutshell", "Python Cookbook". Can't remember if I had "Programming Python" or not, it's not on my shelves here. I might have borrowed it from the university library at the time.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Oluseyi
Oluseyi
Quote:
Original post by CyberSlag5k
This was what was confusing me. I inferred that self referred to a DirectObject derivative because I opened up the Panda Asteroids sample and saw that the call was made within a class that inherited from it.

Yes, it seems clear that it is indeed the DirectObject.accept method that is being called on the derived class instance. Specifically, .accept establishes a mapping between an event and an event handler, so it is being used during object initialization to set up event handling for the instance.

Quote:
I'm a little confused. Is Learning with Python the earlier version of the same book? Their website suggests it is. Is it enough to just read Python for Software Design, or would it be helpful to read its predecessor first?

It's enough to just read Python for Software Design.

Quote:
Thank you very much for all of your help, and for your sharing your rather impressive (some might say scary) level of knowledge, Oluseyi.

Glad to help. [smile]

Quote:
Oh, and it sounds like you've worked with Panda before. What have you done with it? Are you a contributor to the project?

I played with it, briefly, a couple years ago - 2004, 2005. It's improved since then, and I'm interested in looking at it again now that (experimental) Mac support has been finished. I'm not currently contributing to Panda at all, or to any significant Python project, though I have started examining the source code to some and considered submitting feature enhancement and bugfix patches.
CyberSlag5k
CyberSlag5k
Thanks, Fruny.

Quote:

The text for both books is available online, so it should be easy enough to compare.


Is it? I only see the earlier versions available for download. It looks like the rest are headed to Amazon. Maybe I'm missing something?

Quote:

You should have a look at "C++ Coding Standards" by Sutter and Alexandrescu, as well as "C++ Common Knowledge", by Dewhurst.


Are these more "must reads"?

Quote:

As Oluseyi pointed out before, the self argument is always explicitly passed to methods, unlike C++'s implicit this. It refers to the object itself


I hate to sound dense, but I'm still not quite getting this. Does that mean that every member function must have a self argument? They certainly seem to in my Panda example. And then when the function is called, the instance gets passed in for this? So if I had this:

class MyClass:   def MyFunction(self):      #stuffmyClass.MyFunction()


Then myClass (assuming I've instantiated that properly) is the self that would get referred to in #stuff, right? If so, I don't see how that differs from this in C# (I don't remember what this is like in C++).
Without order nothing can exist - without chaos nothing can evolve.
Fruny
Fruny
Quote:
Original post by CyberSlag5k
Are these more "must reads"?

I consider them so, yes.

Quote:
I hate to sound dense, but I'm still not quite getting this. Does that mean that every member function must have a self argument? They certainly seem to in my Panda example.

No, not all of them. classmethod will have a cls argument (it gets the class passed in, while staticmethod won't have a self argument at all.

But otherwise, yes, you must always provide the self parameter in the method.


Quote:
And then when the function is called, the instance gets passed in for this?


class Foo(object):   def a(self, x, y):      print(self, x, y) # get used to the (), they're mandatory in 3.0   @classmethod   def b(cls, x, y):    # The name is just a convention!      print(cls, x, y)    @staticmethod   def c(x, y):      print(x, y)f = Foo()               # this is how you instantiate an objectf.a(42, 666)            # self is f - a Foo instancef.b(42, 666)            # cls is Foo - the Foo class objectf.c(42, 666)            # just x and yFoo.a(f, 42, 666)       # self is f! You used the unbound method 'Foo.a'.Foo.b(42, 666)          # cls is Foo againFoo.c(42, 666)          # just x and y



Quote:
If so, I don't see how that differs from this in C# (I don't remember what this is like in C++).

Basically, it doesn't. It's just that you have to include it in the method's signature.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
CyberSlag5k
CyberSlag5k
Quote:

Basically, it doesn't. It's just that you have to include it in the method's signature.


Oh! The only difference is that it's explicitly declared in a python function, instead of implicitly so in a C#/++ method. I see! I thought I was missing some key functional difference there, and feeling quite dumb about it.

Also, and this is pretty trivial, but I've noticed that in C++ circles, the term function is used, but with C# they're methods. What's the commonly accepted term in Python world?
Without order nothing can exist - without chaos nothing can evolve.
Fruny
Fruny
Quote:
Original post by CyberSlag5k
Also, and this is pretty trivial, but I've noticed that in C++ circles, the term function is used, but with C# they're methods.

In C++, they are member functions.

Quote:
What's the commonly accepted term in Python world?

In python, they are methods.

They are somewhat different from functions at the implementation level, though I believe they've been unifying them. But classes, instances, functions and methods are all objects anyway, so. :P
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
swiftcoder
swiftcoder
Quote:
Original post by Fruny
They are somewhat different from functions at the implementation level, though I believe they've been unifying them. But classes, instances, functions and methods are all objects anyway, so. :P
Methods also have that magikal ability to automatically become delegates when referenced through an instance, but remain methods if referenced through the class - I still have no idea how that works [smile]
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
Ezbez
Ezbez
Quote:
Original post by swiftcoder
Quote:
Original post by Fruny
They are somewhat different from functions at the implementation level, though I believe they've been unifying them. But classes, instances, functions and methods are all objects anyway, so. :P
Methods also have that magikal ability to automatically become delegates when referenced through an instance, but remain methods if referenced through the class - I still have no idea how that works [smile]


Could someone elaborate on this? I'm thinking that you mean this:

class Foo:    def Bar(self):        print(self.x)    def __init__(self,x):        self.x = xf = Foo(5)func = f.Barfunc() #prints 5func = Foo.Barfunc() #error! Needs a "self" passed infunc(f)#prints 5


Am I right? If so, then I agree. This is a pretty awesome thing. (Much nicer than C++-style function pointers to member functions, at least!)
Fruny
Fruny
Quote:
Original post by Ezbez
Could someone elaborate on this? I'm thinking that you mean this (snip!)


Yeah, that's precisely it. f.Bar is a bound method, while Foo.Bar is an unbound method.

As for C++ pointers to member functions, remember that here, Python manages the lifetime of the objects for you. If you keep a reference to a bound method around, the associated object will be kept alive!
In C++, you are supposed to manage all that stuff yourself. If it were otherwise, people would scream. Library implementations exist, like boost::bind or tr1::bind. They do a copy of the bound object. And type erasure in boost::function involves dynamic allocation. Those are design decisions that may be incompatible with your needs.
Python hides that by asserting it to be the way things are in the language, along with dynamic type. But the costs are still there.

[Edited by - Fruny on March 2, 2009 11:42:41 PM]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
CyberSlag5k
CyberSlag5k
Dude, the PyGame Python game programming tutorials are fan-frickin'-tastic. They're clear and comprehensive, exactly the type of document I've been looking for. I'm only on the second one, and I'm not sure how far they go, but this is a great starting point, if nothing more.

That was a great suggestion!
Without order nothing can exist - without chaos nothing can evolve.
rmtew
rmtew
Quote:
Original post by Oluseyi
Quote:
Original post by CyberSlag5k
That's exactly what I'm looking for. If I follow, this is exactly what I'd do in a C++/# program as well. I was attempting to do this, ironically, without the classes, as I thought I was meant to. I know Python is Object Oriented, but thus far is has a more in-line, functional feel to it, which I know is not right. It seemed like I should be constructing the pieces of a big global namespace across my files.

Python is multi-paradigm. Objects are truly first-class, but there is no imposition of programming paradigm. You can write procedural, object-oriented, functional and generic code quite easily, giving you the freedom to choose the best fit approach for your problem.

Python does not allow you to construct explicit namespaces. They are implicit in the declarations of classes and modules. It also does not support partial classes, so your namespaces must effectively be declared in one shot. The exception is packages, which may correspond to the filesystem: if you have a module X corresponding to a directory X, all files in that directory comprise elements of the namespace and you can direct the explicit construction of that namespace and turn the module into a package by creating a file named __init__.py. Read more here.


>>> class DingDangDo:...     pass...>>> import imp>>> module = imp.new_module("DingADong")>>> module.DingDangDo = DingDangDo>>> import sys>>> sys.modules["DingADong"] = module>>>>>> import DingADong>>> DingADong.DingDangDo<class __main__.DingDangDo at 0x02229FC0>>>> from DingADong import DingDangDo>>> DingDangDo<class __main__.DingDangDo at 0x02229FC0>>>>


Certainly, you should not do it unless you know how the existing Python namespacing/import system works, as whatever you create will be available for import along with what that provides. And you should not not do it, because people say that you shouldn't, when they have no experience or need for it. It's this sort of metaprogramming which makes Python great when used for a reason.

The game Anachronox had a custom scripting language called APE where all the functions defined by its scripts were present in and operated on the same shared variable area. Could you recreate this using Python for a new game? Absolutely.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.