|
This Tutorial will show you how to:
Modules let you share common code across multiple files, so you only have any given function or class defined in one place. This is a software-engineering practice that you don't want to learn the hard way!
ContentsModulesIn Jython, a module is just a file with a bunch of definitions in it. Definitions can be:
This module just has one comment and one function. The function, hello_world, has no parameters, and simply returns the string "Hello, world!". This module can be placed anywhere you want (in your Wiz directory tree), and can be named anything you want. You can put as many functions as you like in it. You can also put in classes and variables (although variables aren't really recommended.) For our example, we're going to call the module testmodule.py, and we'll put it in the directory wiz/rhialto/py/test/, which you can do using FTP. (In your own wiz dir, of course.) Creating Modules To create To make it an official module, usable by other Jython code, you have to do something a bit wacky: you have to put another file in the same directory called "__init__.py". Moreover, you have to put __init__.py files in every parent directory of the module, up to and including your wiz directory. So in this case, we actually have to upload two files:
This definitely clutters up your directories, but that's how Python works, and you don't want to go complaining about Python's design, or the highly irritable Python Community Mafia (which has nothing to do with Wyvern) will treat you with icy disdain for the remainder of your days. So remember: it's a great design. Besides, you can stick useful Python statements in those __init__.py files, such as 'print "I am an __init__.py file.". Using Modules To use a module, you just import it using the
Let's look at some examples. In the following examples, I'm using the Top Secret Wyvern Python Interpreter Console, which is hidden from all but Elder (and some Senior) Wizards because it's kinda dangerous to use it in a running game server. This console lets me type in Python statments and evaluate them on the fly. You can pretty much achieve the same effect by writing a Jython object and executing it with the normal game mechanisms (such as cloning it, or casting if if it's a spell). By forcing you to stick it in a file, it helps prevent typos that will destroy the universe. Example 1 >>> import wyvern In this example, I typed import wyvern and it added the top-level package "wyvern" to my script's namespace. That means I can use the name in my script. After I've done that, I can type the next line, which specifies the entire path to the function, in all its lengthy long-ness. But it works! There's a better way, though, in the next example. Example 2 >>> import wyvern.wiz.rhialto.py.test.testmodule This version looks almost the same as the first one. There's a big difference, though - I only have to type the full path to the module in the import statement. After that, I can just say "testmodule.<whatever>" without having to type it all out. Nice. Example 3The third (and possibly most common) way to do it is: >>>from wyvern.wiz.rhialto.py.test.testmodule import hello_world
>>>hello_world() (Incidentally, the Python keywords from and import are blue above to highlight the fact that they're Python keywords, and we use blue for keywords in all the HTML code samples in these Tutorials.) In this last example, I'm importing a particular definition from my
Example 4 Let's say I have multiple functions defined in
I can import testmodule as in Example 1 or 2 above, and invoke the functions with "testmodule.<function>()", like so: >>> import wyvern.wiz.rhialto.py.test.testmodule>>> testmodule.hello_world() 'Hello, world!' >>> testmodule.goodbye_world() Goodbye, cruel world!' I could also import the functions directly, like this:
>>> from wyvern.wiz.rhialto.py.test.testmodule import hello_world, goodbye_world In other words, I can specify which names I want to import, separated by commas. Finally, although it's considered bad style for various reasons, you can also import all of the names from a module by doing this:
>>> from wyvern.wiz.rhialto.py.test.testmodule import * That will grab both functions. If you have 100 functions defined in the module, well, you'll have them all in your own namespace. It's a bad idea because the names can collide with other names from your own file, or from other modules, and you may get weird, difficult-to-track-down bugs in your code. So in Wyvern, just don't use import *. Now we're ready to take a look at subclassing.
SubclassesWe've already shown you how to extend a Java class with your Jython class. We do it in just about every other tutorial. Take a look at the command_test.py example to see a Jython subclass of the Wyvern Java classwyvern.lib.classes.DynamicObject. In addition to subclassing Java classes, you can also subclass other Jython classes. Jython has one distinct difference: you can extend more than one Jython superclass. For example, you can type: class foo(A, B, C): Where A, B and C are all Jython classes. (One of them is even allowed to be a Java class.) This feature is called "Multiple Inheritance", and can get you into trouble unless you know what you're doing, so you should ask a Wizard for advice before trying it. Now we're ready to see a real example.
Minimal Subclassing ExampleIn this example, I'm going to define two classes, in different modules:
I defined some simple, working Jython code in two files for this example. Take a look at the code, and we'll discuss it below.
Take a look at the code and see if you can figure out what's going on. We'll explain it below. Example ExplainedOK, so what did we do in the previous example? First, we defined Class Note that Second, we defined the Note that Note also that I tried this, and cloning wiz/rhialto/python/testA/supertest.py got me a ruby key called "supertest", while cloning wiz/rhialto/python/testB/subtest.py got me a wooden key called "subtest". Worked like a charm! If you have questions or feedback about this module, please send us email. The easiest approach is probably to mail Rhialto from inside the game, in one of the post offices.
|