lrh9 95 Posting Whiz in Training

Check out the "code" module. It has functions to emulate a Python interpreter.

lrh9 95 Posting Whiz in Training

I managed to use the import hook.

http://www.daniweb.com/forums/thread251208.html

lrh9 95 Posting Whiz in Training
lrh9 95 Posting Whiz in Training

Without supporting or opposing cloud computing and cloud operating and software services, the statement that desktop computers will always exist for resource intensive applications may not be true.

The primary factor preventing centralized, networked systems from providing resource intensive services is data transfer width and rate. With modern operating systems residing in as much as two gigabytes of memory constantly at any given nanosecond, it would take at least approximately two and a half hours to transfer a single nanosecond slice of the entire operating system on a typical low end broadband connection. That assumes an ideal that the maximum bandwidth per second is used. That isn't always the case.

Now certainly redesign would reduce the amount of data transferred and how often data needed to be transferred, but the point is that tasks such as graphics rendering and bulk data processing over network are limited by data transfer rates.

However, as data transfer rates and bandwidths increase, this barrier becomes less of a factor. All ready, locally networked mainframes can provide centralized resource intensive services to node computers. If data transfer services improve sufficiently then it may be feasible in the future to provide resource intensive services over a cloud environment.

lrh9 95 Posting Whiz in Training

That is in fact the case.

To fix this behavior, it would simply be a matter of looping through the built-in modules if that dictionary exists and reloading them.

Now I need to determine how to accomplish that.

lrh9 95 Posting Whiz in Training

My first guess about what happened would be that the IDLE imports random when it starts. It probably has the random module all ready cached. If a module is cached, importing it will merely result in the cached module's finder being used and/or the cached module being returned. This would skip the new hook you've inserted.

I bet that if I had reloaded the random module, it would have worked in the IDLE.

Time to test.

lrh9 95 Posting Whiz in Training

Actually, please feel free to contribute help, but I managed to create a working example of an import hook.

class Restricted:

    def __init__(self):
        print("Initializing...")
        self.forbidden = list()

    def find_module(self, module_name, package_path):
        if package_path:
            print("Searching the path... Return.")
            return
        if module_name in self.forbidden:
            return self

    def load_module(self, module_name):
        raise ImportError

import sys

sys.meta_path.append(Restricted())
print(sys.meta_path)
sys.meta_path[0].forbidden.append('random')
print(sys.meta_path[0].forbidden)
import random
print(random.random())

The problem occurred when I executed the program from the Python IDLE, but when I executed the program from the command line it worked.

IDLE output:

Initializing...
[<__main__.Restricted object at 0x0000000003C6A9E8>]

0.114156604708

Command line output:

Initializing...
[<__main__.Restricted object at 0x0000000002F69400>]

Traceback <most recent call last>"
File "C:\Users\lrh9\Documents\Code\Personal Code\test.py", line 23, in <module>
import random
File "C:\Users\lrh9\Documents\Code\Personal Code\test.py", line 15, in load_module
raise ImportError
ImportError

Strange.

lrh9 95 Posting Whiz in Training

And I can't get anything I write to work.

I'm so far off course I think I just need a working example of import hooks in action.

I've looked for examples on the Internet, but they only show what looks like correct code. They never show that code in action. They never try to import something and show what their hook does.

lrh9 95 Posting Whiz in Training

OK. I did some reading of PEP302, and apparently an import hook's find_module method only handles the qualified module. Basically, when importing a module such as ctypes.util, by the time find_module('ctypes.util') is called, ctypes has all ready been imported.

I tried registering my importer as a hook, but it didn't do anything.

lrh9 95 Posting Whiz in Training

Yes, imp.load_source has been said to be "obsolete" since at least python 1.5, but it's still alive and well. Moreover, the function has never been made to issue a deprecation warning, which is the usual way to sort out python functionality. It may be that is goes away some day, but I think that day is in a far distant future, and there will be plenty of time to adapt when (and if) it comes.

I'm all ready fairly on my way in implementing a custom importer that removes the import once features of the standard Python import.

Here's the thread I started in case you missed it.

lrh9 95 Posting Whiz in Training

(A quine is a program that produces its own source as its output, typically to a file.)

import sys
ifile = sys.argv[0]
counter = 0
istream = open(ifile)
source = istream.readlines()
source[2] = 'counter = ' + str(counter + 1) + '\n'
if counter == 0:
    original = str(ifile)
    source.insert(5, 'original = r\'' + str(original) + '\'\n')
istream.close()
ofile = list(original)
ofile.insert(-3, str(counter))
ofile = ''.join(ofile)
ostream = open(ofile, 'w')
ostream.writelines(source)
ostream.close()

It is a naive implementation in that it depends on code that assumes that the new executables are created in and stay in the same directory as the original executable.

Moving the new executable or altering any executable to store the executable in a different directory will break the chain.

The first step to improving the code would be to alter the code so that it can function regardless if it is moved.

After that, I'd like to include code that would automatically execute the new executable. (This is dangerous code that could be considered a form of virus in that it replicates until it consumes all hard disk space. I'll be sure to write a warning against executing the program or remove the code if I am told to cease and desist by moderators.)

lrh9 95 Posting Whiz in Training

I've read up on PEP 302 some more, and I've looked over importlib and the abstract base classes some more.

I think I'm understanding it better.

Basically, I need an object known as a finder first. I pass the name of the module I want to import to it, and then it returns a loader for the module. The loader is responsible for actually importing the module.

I haven't written the loader yet, but here is what I came up with for the finder.

from importlib import abc
import imp

class CopyImporter(abc.Finder, abc.PyPycLoader):

    def find_module(self, fullname, path = None):
        try:
            self.module = imp.find_module(fullname, path)
        except ImportError:
            return None
        else:
            return self

    def load_module(self):
        pass

Is this right? This object acts as both the finder and the loader, so it is appropriate for the finder to return itself.

If a loader can't be found, None is returned. If imp.find_module() can't find the module, then it raises an ImportError. That's why I handled the ImportError exception.

The main thing I'm concerned about is the fact that imp.find_module() doesn't handle dotted names. It can only find one module at a time. My question is what is a normal finder supposed to do? Is it supposed to handle dotted names by itself, or is that for import statement code to handle? The main reason I'm unclear on this is fullname is used to identify the module. Is that a full, dotted name? Also, does that refer to the …

lrh9 95 Posting Whiz in Training

Thank you for the response. I've located the scons website and bookmarked it. I'll have a look later. Can you think of anything in particular you'd want in a directory and file management program?

lrh9 95 Posting Whiz in Training

I'm thinking about writing a small command line directory management program in Python. The most basic functionality I want is to be able to compare the the files in a directory and sub-directory, and if there are any duplicates then delete the lower most duplicate.

I all ready have a basic idea of how to accomplish that. Merely hash both files and compare the hash values. If the hash values are equivalent, then they are the same. However, I'm not sure on the specifics of how to accomplish it. I know the data has to be read from each file and then hashed to do the comparison. However, what is the best method for reading the data? I'll be dealing with large files, possibly upwards of 4GB, so the program needs to be able to handle this.

What are some other good tools to include? I'm thinking about writing some file renaming tools as well.

lrh9 95 Posting Whiz in Training

vegaseat wrote some good code. I did some experimentation with bindings. If you decide to use bindings, there is a very easy way to determine the widget that called the event. The event object has an attribute called "widget". This attribute contains the numerical name of the widget which called the event. I haven't experimented with using a widget's numerical name to perform actions on and with that widget, but I'm sure the functionality exists somewhere.

I suppose it would help if I taught you how I found out about the event's "widget" attribute. Every object in Python has a dictionary of attributes and methods. You can see the contents of this dictionary with:

print(dir(object))

Now any attributes and methods intended to be available to access from the outside will generally be in an object's "__dict__" attribute. If you wanted to find out the attributes and methods of an event for instance, you could use this code:

from tkinter import *

def myevent(event):
    for key in event.__dict__:
        print(str(key), ":", str(event.__dict__[key]))

root = Tk()

mybutton = Button(text = "My Button")
mybutton.bind("<Button-1>", myevent)
mybutton.pack()

root.mainloop()

Run this script, and then look in the Python shell to see the results. ("print" prints to stdout, not to the GUI.)

lrh9 95 Posting Whiz in Training

1) Thread titles should be descriptive. A generic request for help is not descriptive.

2) This appears to be homework. Part of homework is to take the initiative to learn for yourself. That means you must complete the essential portions of the assignment for yourself. No one will do it for you.

lrh9 95 Posting Whiz in Training

Edit: I'm sorry. I didn't realize that you wanted the button to set up a condition so that if another button is pressed something would be executed, or do you just want to check which button called the function?

lrh9 95 Posting Whiz in Training

Can you give an example of what those certain objects are?

So far the only objects I've been interested in generating true copies of are module objects and function objects.

I learned how to create a module object, so I was going to learn how to create a custom importer. I'm probably still going to do this because it will allow me to incorporate some additional features.

However, when I attempted to create a true copy of a function object, it failed miserably and was too complex for me to figure out. deepcopy claims to be able to copy function objects, but when I used it, I did not get the desired behavior.

lrh9 95 Posting Whiz in Training

I am aware of the copy module, but it will not copy certain objects I need to copy.

See my initial post.

lrh9 95 Posting Whiz in Training

Only mutable objects are passed by reference, since they can change internally. So, assignment will not create a true copy, just an alias. The module copy handles many mutable objects. However there are more complex objects than cannot be easily copied. For instance a recursive situation.

Right. The copy module itself lists some of the objects it doesn't copy. I don't know why it would be so hard to create a set of functions and classes to handle the copy of objects. Almost any object or data type in Python is in fact a first class object.

lrh9 95 Posting Whiz in Training

as someone here once showed me:

x = [1, 2, 3]

y = x[:] # y is now a copy of x

That only works on lists, but thanks for pointing that out.

lrh9 95 Posting Whiz in Training

All though it is true that Python has no true protected and private attributes and methods, certain conventions indicate that a attribute or method should be protected or private.

programmersbook is right about the leading double underscore. I was wrong about it. I had only ever seen the double underscore used to wrap attributes and methods, but a leaded underscore does obfuscate the attribute or method. I was not aware of this property until now. Thank you for teaching me.

A more accurate statement would be that attributes or methods with a single leading underscore are protected, attributes or methods with a double leading underscore are private, and attributes or methods wrapped in double underscores are special.

lrh9 95 Posting Whiz in Training

Lately I've been writing a lot of code involving the creation of new objects, and I quickly come to find that Python almost always creates a reference to an object instead of a new object. I understand the importance of conserving memory usage, but in this instance I actually need a true copy.

My problem is that I have yet to find anything in Python that can quickly generate a true copy of all objects. I am aware of the copy module, but it will not copy certain objects I need to copy. I have had some success experimenting with creating a new, blank object and initializing it to be the same as another object, but this is a sometimes lengthy and complex process. My question is if there is a feature that allows programmers to easily copy objects using a simple assignment.

Python is a good language, but it seems like its lacking an intuitive way to copy objects.

lrh9 95 Posting Whiz in Training

Actually, this code is wrong. I retested it, and I noticed an error. This code when run prints "This is my class both times."

I'll get to the bottom of it.

P.S. I realize what it is. The new_method definition doesn't create a new function each time it is called, its name is merely rebound to the new function.

lrh9 95 Posting Whiz in Training

It was a ***** to do, but I believe I figured out how to decorate each and every method in a class by decorating only the class itself.

def method_decorator(class_declaration):
    class NewClass():
        pass
    for key in class_declaration.__dict__:
        if hasattr(class_declaration.__dict__[key], '__call__'):
            def new_method(*args, **kwargs):
                print("This is a decorator.") #Replace this with your code.
                class_declaration.__dict__[key](*args, **kwargs)
            setattr(NewClass, str(key), new_method)
    return NewClass

@method_decorator
class MyClass(object):

    def __init__(self):
        print("This is my class.")

    def method(self):
        print("This is my method.")

x = MyClass()
x.method()
Gribouillis commented: A class decorator is the solution. +2
lrh9 95 Posting Whiz in Training

mmmm, i would use decorators as well... i was just thinking if you didnt want to have to type that arbitraryFunction() that you probably wouldn't want to type @arbitraryDecorator

I didn't catch that reply.

If you used decorators you would have to copy and paste the decorator for each method. I can understand the problem there.

The more interesting trick would be to create a decorator that could handle each and every method in a class as per the user's specifications.

I think it might be possible. I tested some code and I discovered that a decorator can also be applied to a class.

Now what I was thinking is that this decorator could loop through each callable name in the class dictionary and then manipulate this name the way a normal decorator does. It might be simple for a basic class, but a problem that occurred to me was if the class inherits other classes, and also the issue of method resolution order.

lrh9 95 Posting Whiz in Training

Try using decorators.

They are a language feature in at least Python 3.0 that perform code on a function or method defined after them. Optionally, they can return a new function that will be assigned to the newly defined function. There are function decorators and class decorators. I haven't studied them in depth, so I could be wrong about some things or there could be more to them, but they seem to be a solution to your problem.

Here's the code using a function decorator in case I wanted "Hello, world!" printed whenever one of my functions is called.

def say_hello(function):
    def new_function():
        print("Hello, world!")
        function()
    return new_function

@say_hello
def myfunc():
    print("This is my function.")

@say_hello
def mysecondfunc():
    print("This is my second function.")

myfunc()
mysecondfunc()

The resulting output should be:

Hello, world!
This is my function.
Hello, world!
This is my second function.

The first function is the decorator. It takes only one argument, the function it is to modify or use.

The "@say_hello" is the decorator syntax. It indicates to the interpreter which function or class I want to call to use or modify the function.

Inside the first function, it defines a new function that prints "Hello, world!" and executes the function it took as an argument. I should mention that I think that if it is used on functions with arguments, this new function definition should accept *args and **kwargs in order to support your function arguments.

lrh9 95 Posting Whiz in Training

Here's how I would've written it using functional programming.

It's not necessarily the best way to do it, it's just the way I would have done it. I've included some commentary in the program comments that you should read over.

If I find the time I would like to show you the same program written using object oriented code, but object oriented code requires more thought up front than functional code. The rewards are worth it though and can speed up development later in the software cycle.

Some people might disagree with my style, and they have the right to their opinions, but if you want to learn about style from people that are true leaders in the Python community - someone in the know - then refer to PEP 8.

http://www.python.org/dev/peps/pep-0008/

#!/usr/bin/env python

from Tkinter import *
import pygame.mixer
from pygame.mixer import Sound

pygame.mixer.init()

"""According to pygame documentation, initiating pygame is unnecessary
if you are only using a module within the package. In that case only initiating
the module you are using is necessary. It can sometimes be faster."""

playlist = []

CAMERA_SOUND = Sound(r'e:\Peter\Python_stuff\data\Music\camera1.wav')
ONE_SOUND = Sound(r'e:\Peter\Python_stuff\data\Music\one.wav')
WRONG_SOUND = Sound(r'e:\Peter\Python_stuff\data\Music\wrong.wav')

"""Raw strings allow you to type special characters without escaping them.
To create a raw string, simply prepend the r character before the string,
or wrap the string in triple quotes.
Python variable names are generally nouns describing the object.
Descriptive names are longer but more informative.
The general naming convention …
lrh9 95 Posting Whiz in Training

I have heard of this and understand this. Although I doubt I'll be importing my module...

Understandable, but something I do is keep a basic python file that I can copy and edit on the fly.

#!/usr/bin/env python

def main():
    pass

if __name__ == "__main__":
    main()

The line at the beginning is a comment for the courtesy of Linux users. It is called a shebang, and it lets the Linux OS know where the Python interpreter is so that when a Linux user executes the file it is automatically opened with the interpreter. It does not affect people who use other operating systems.

You don't have to remove the pass statement in main() to add code. Simply write after it. I include the pass statement to prevent an exception if the script is executed as a program, even if there is no main() code.

I don't think the main() function is exactly Pythonic, but I use it so that I don't pollute the global namespace.

To each their own I guess.

lrh9 95 Posting Whiz in Training

Whitespace is recommended to make Python code clearer. Traditionally there is no space between related lines of code. A single line is recommended between different code sections and function definitions. Two lines are recommended between class definitions and I use two lines in method declarations if the methods are different enough to be logically separated. (For instance, I'll write my methods for accessing one property, and then I'll enter two blank lines and type more methods for accessing another property.)

I might have considered importing just the specific function I needed from pygame.mixer, or importing all functions and attributes.

I don't think you've been introduced to Python's object oriented features yet, but I probably would have used a few classes too to simplify some things.

Also, "if __name__ == '__main__'" is understood to be a standard Python idiom that you should research.

There are a few questions I have.

When you add a sound to the playlist, you automatically play it. Is that the functionality you desire?

lrh9 95 Posting Whiz in Training

I was wondering if anyone knows of any resources about building a custom importer.

I've found this: http://www.doughellmann.com/PyMOTW/sys/imports.html.

I am also aware of PEP 302 and PEP 369 and imp and importlib.

Are there any other resources I might need?

lrh9 95 Posting Whiz in Training

I spotted this and thought it might help answer your questions. Especially section 24.1.5.

http://docs.python.org/library/tkinter.html

lrh9 95 Posting Whiz in Training

Actually, a frame alone is enough to produce the effect I desired. I'm sorry to waste space and time.

Here's the code.

#!/usr/bin/env python
#Python 3.1

from tkinter import *

master = Tk()
nameentryframe = Frame(master, background = 'BLACK', borderwidth = 1, relief = SUNKEN)
nameentry = Entry(nameentryframe)
nameentryframe.pack()
nameentry.pack()

master.mainloop()
lrh9 95 Posting Whiz in Training

I'm wondering if it's possible to change the border color of a tkinter entry widget border. I don't think it is, because no such option exists in relevant documentation. You can change the width, but that just results in the whitespace being recessed - creating a raised 3d border.

If it can't be done, would it be more valid to use a frame around the widget? Is it possible to combine the border width and a frame to create a good appearance?

Thank you.

lrh9 95 Posting Whiz in Training

Dual boot with XP and whatever version of Unix/Linux has my fancy.

lrh9 95 Posting Whiz in Training

What do you mean by "Standardize how it draws widgets"? Do you mean that tkinter or Tk uses an API of the system telling the system to draw a certain widget instead of drawing the widget on its own?

Possibly. I don't know. Tkinter could also define its own API.

lrh9 95 Posting Whiz in Training

Private attributes are always with "__" double underscore.

Taken directly from the zipfile module:

def _check_zipfile(fp):    #Begins with a single underscore. Protected function. Will not be returned by zipfile.__all__
    #...

def is_zipfile(filename):    #Public function. Will be returned by zipfile.__all__
    """Quickly see if a file is a ZIP file by checking the magic number.

    The filename argument may be a file or file-like object too.
    """
    #...

I commented on both functions to explain the difference. Special attributes and methods are wrapped in double underscores, but they're different.

In fact, the best way to describe it is that a public attribute or function does not begin with an underscore, a protected attribute or function does begin with an underscore, and a private attribute or function is wrapped in two underscores.

You all ready know what public means, but in object oriented programming protected means that only a class or subclass can access the attribute or method, and private means that only the class itself can access the attribute or method.

(Actually, in Python you can access attributes and methods wrapped in double underscores from outside the class, but double underscores always signify data or methods that are specific to the class object itself.)

lrh9 95 Posting Whiz in Training

So how, then, does Tk manage to provide windows which look 'native' for the different operating systems?

I don't know the way it technically does it, but my best guess is that it uses an API - application programming interface - to standardize how it draws widgets without being aware of operating system details.

http://en.wikipedia.org/wiki/Application_programming_interface

lrh9 95 Posting Whiz in Training

The class if functionally correct. A few things I'd like to suggest.

1) As far as I'm aware, protected names usually begin with one underscore.

self._name #"Correct"
self.__name #"Incorrect"

2) I'd probably put an underscore in front of "get_name" and "set_name" and use the property to handle attribute access.

3) Whenever I consider using the "==" comparison operator, I consider using "is".

if name is "":

is much clearer than

if name == "":

In fact, I'd probably import string earlier in the module and do this:

import string

if name is not in string.whitespace:

The python module string contains string constants that might be useful to you. It will be a great help to you if you know the python standard library, or are at least able to navigate it.

4) There is another syntax for a property involving class decorators. You don't need to understand how class decorators work at the moment, but you should be able to recognize that this:

@property
def name(self):
    return self._name

@name.setter
def name(self, value):
    self._name = value

is the same as:

def _get_name(self):
    return self._name

def _set_name(self, value):
    self._name = value

name = property(_get_name, _set_name)
lrh9 95 Posting Whiz in Training

Have you overseen my solution? (See above, 3rd code block.) It solves your problem and circumvents the "read-only-ness" of __dict__.

I looked it over, but apparently load_source is obsolete. I realize it will still be in the imp module, but there is no telling when they will deprecate and remove it.

After looking over the imp module, I don't think it will be too difficult to implement a custom import solution that fulfills my specification.

The imp module has a function called new_module which returns a new module.

According to PEP 302 at the end of the section "Specification part 1: The Importer Protocol", the way a module object is created is a empty module object is created and then the module file's code is executed in the module object's dictionary.

This simple code will load the random module from a Python 3.1 installation on the C:\ drive.

import imp

file_stream = open(r'c:\python31\lib\random.py')
module_code = file_stream.read()
random = imp.new_module('random')
exec(module_code, random.__dict__)
print(random.random())

This code is very basic, so there are some differences between this code and Python's implementation of import. However, more code can be added to complete additional functions of Python's import.

lrh9 95 Posting Whiz in Training

If it interests you, I think that the code for Python's IDLE is available in the Python library. If it is, you can edit it to your liking.

lrh9 95 Posting Whiz in Training

There are other options as well.

Make both functions methods of a class, and use class attributes to store relevant data.

Combine both functions into one.

lrh9 95 Posting Whiz in Training

I remember watching a Stargate SG-1 episode called "Torment of Tantalus", and SG-1 find an ancient repository of information created by a council of allied alien races. The first page was a glossary containing basic definitions for the language in the repository, and it was a 3d hologram of the elements.

The premise was that a race who wanted to ensure universal communication would create a language based on something you could be certain was common to everyone and everything, which is the basic building blocks of matter.

According to the anthropomorphic principle, any race sufficiently advanced enough to travel the stars would be able to detect electromagnetic radiation. That is because only electromagnetic energy can travel through the vacuum of space. That means that all species sufficiently advanced enough to travel the stars would have some form of vision.

I'm not sure it would qualify as simple, but it could qualify as truly universal.

lrh9 95 Posting Whiz in Training

I'm just wondering why the Library class has a container for book information. Is the book information a temporary container?

lrh9 95 Posting Whiz in Training

I did some quick testing, and my idea of setting the self object to a module won't work. It makes the class's __dict__ attribute a readonly attribute. Which I find strange, because I remember from earlier experimentation storing a new variable in a module object.

lrh9 95 Posting Whiz in Training

I did some more research, and after learning that a module is in fact an object and learning about introspection, I think I finally came up with a decent solution.

Setting a classes dictionary to that of another classes dictionary effectively makes it a copy of that class. Correct? So creating a dummy class and setting its dictionary to that of another module's dictionary effectively makes it a copy of that module. Correct? Using the dict() function to copy the dictionary is a true copy, instead of creating a reference. So here is the final solution I wrote.

class Module_Replicator:

def __init__(self, module_object):
    self.__dict__ = dict(module_object.__dict__)

import random

mymodcopy = Module_Replicator(random)

print(random.BPF)
print(mymodcopy.BPF)
mymodcopy.BPF = 1
print(random.BPF)
print(mymodcopy.BPF)

Now I'm sure it's not a perfect solution. So what if anything should I do differently? For one thing, my object and the module object isn't the same thing. Meaning that comparing the two object's for sameness will return false. How do I fix this? One plausible solution I considered - but have not tested - is in the initialization of the object setting the self object as the module object and then performing a true copy of the module's dictionary. Does anyone see any other problems?

lrh9 95 Posting Whiz in Training

For Christmas? The meal usually. Next year I'm thinking about celebrating Hanukkah, but I'll have to learn about it first.

lrh9 95 Posting Whiz in Training

The class wrapper for a module is a brilliant idea. It might even be dynamically generated so that it would support all modules compatible with the Python version for it.

What are mixins? I get the general abstract that a class composed of mixins is an object that pools similar and related functionality, but you might need to clarify and expound.

I have a general use case, or else I wouldn't have a plan for a program, but how do I arrive at a clear and specific use case? The system I'm working on is general purpose and dynamic. I've only recently begun working with Python. Don't get me wrong. I've become technically proficient and I know my way around code and documentation - so I don't need to learn the mechanics of Python - but I don't always no the correct way to handle the computer science or software design. For instance, my idea to create a custom import system - all though technically correct - was incorrect in terms of computer science and software design.

lrh9 95 Posting Whiz in Training

I've been doing some more research and testing, and I've hit a roadblock. While an object can have a reference to an imported module, it doesn't actually have its own copy of the module. Somehow Python only imports the module once, and somehow each and every agent object points directly to this module. That means modifying the variables in one agent's module modifies those variables in agent's with the same module, and reloading one agent's module reloads it for all agent's.

I know of no easy way to alter this behavior. I'm thinking I'm going to have to try to write my own importer to achieve the results I desire.

lrh9 95 Posting Whiz in Training