[Tutor] Why does this function execute before being called?

2015-11-07 Thread Chris Roy-Smith

Hi,
Environment:
Python 2.7
Linux (Ubuntu 15.10)

I am experiencing a problem with the code below running the "genF" 
function on opening the second window. I expected that function to be 
executed on clicking the 'fill text' button. The text widget gets filled 
on opening the window. This is my first attempt at opening a second 
window, so I expect I have done something stupid.



#! /usr/bin/python
from Tkinter import *

root=Tk()


def genF(ofield):
for x in range(10):
ofield.insert(END, x)
ofield.insert(END, "\n")


def second():
main=Toplevel(root)
ofield=Text(main, height=15, width=15)
ofield.pack()
B3=Button(main, text='exit', command=main.destroy)
B3.pack()
B4=Button(main, text='fill text', command=genF(ofield))
B4.pack()
main.mainloop()

b1=Button(root, text='open second window', command=second)
b1.pack()
b2=Button(root, text='exit', command=root.destroy)
b2.pack()
root.mainloop()


Thanks,
Chris
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Regarding to kivy installation

2015-11-07 Thread shubham sharma
Respected sir/madam,
hello to all members of python.org . I had successfully downloaded kivy on
window7 64-bit version.but when i try to install it then it show me error
like:
 Traceback (most recent call last):
   File "C:/Python27/kivyhello.py", line 4, in 
 from kivy.app import App
   File "C:/Python27\kivy\app.py", line 316, in 
 from kivy.base import runTouchApp, stopTouchApp
   File "C:/Python27\kivy\base.py", line 30, in 
 from kivy.event import EventDispatcher
   File "C:/Python27\kivy\event.py", line 8, in 
 import kivy._event
 ImportError: DLL load failed: %1 is not a valid Win32 application.and the
application close .
i kindly request to all please suggest me some ways to solve it .
Thank you
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Why does this function execute before being called?

2015-11-07 Thread Alan Gauld

On 07/11/15 04:34, Chris Roy-Smith wrote:


def genF(ofield): ...
 for x in range(10):



def second():
 main=Toplevel(root)
 ofield=Text(main, height=15, width=15)
 ofield.pack()
 B3=Button(main, text='exit', command=main.destroy)
 B3.pack()
 B4=Button(main, text='fill text', command=genF(ofield))


You call a function by sup[plying the parens after its name.
So the function gets called here. The normal way to circumvent
that in Tkinter is to use a lambda expression to defer execution,
like so:

B4=Button(main, text='fill text', command=lambda wgt=ofield : genF(wgt))


 B4.pack()
 main.mainloop()


I'm not sure you need the second mainloop. I think the
root level mainloop will work for your window too.


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Regarding to kivy installation

2015-11-07 Thread Alan Gauld

On 07/11/15 03:39, shubham sharma wrote:

Respected sir/madam,
hello to all members of python.org . I had successfully downloaded kivy on
window7 64-bit version.but when i try to install it then it show me error
like:
  Traceback (most recent call last):
File "C:/Python27/kivyhello.py", line 4, in 
  from kivy.app import App
File "C:/Python27\kivy\app.py", line 316, in 
  from kivy.base import runTouchApp, stopTouchApp
File "C:/Python27\kivy\base.py", line 30, in 
  from kivy.event import EventDispatcher
File "C:/Python27\kivy\event.py", line 8, in 
  import kivy._event
  ImportError: DLL load failed: %1 is not a valid Win32 application.and the
application close .
i kindly request to all please suggest me some ways to solve it .


Can you tell us exactly what you did to install it after you
downloaded it?

Also, I think there is a kivy support forum who may be able
give more detailed help than we can on the tutor list.

Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] command line list arguments

2015-11-07 Thread Garry Willgoose
I want to input a python list as a command line argument as for example

python weathering-sens.py -daughter ['p0-50-50','p0-0-0-100’]

but what I get from sys.argv is [p0-50-50,p0-0-0-100] without the string 
delimiters on the list elements. I’m probably missing something really simple 
because sys.argv returns strings and probably strips the string delimiters in 
that conversion … but is there any way that I can keep the string delimiters so 
that inside the code I can just go (if arg is ['p0-50-50','p0-0-0-100’])

a=eval(arg)

or is there no alternative to doing this

python weathering-sens.py -daughter 'p0-50-50’ 'p0-0-0-100’

and doing the legwork of interpreting all the arguments individually (I’ve seen 
an example of this on the web).





___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] command line list arguments

2015-11-07 Thread Chris Warrick
On 7 November 2015 at 02:56, Garry Willgoose
 wrote:
> I want to input a python list as a command line argument as for example
>
> python weathering-sens.py -daughter ['p0-50-50','p0-0-0-100’]
>
> but what I get from sys.argv is [p0-50-50,p0-0-0-100] without the string 
> delimiters on the list elements. I’m probably missing something really simple 
> because sys.argv returns strings and probably strips the string delimiters in 
> that conversion … but is there any way that I can keep the string delimiters 
> so that inside the code I can just go (if arg is ['p0-50-50','p0-0-0-100’])
>
> a=eval(arg)
>
> or is there no alternative to doing this
>
> python weathering-sens.py -daughter 'p0-50-50’ 'p0-0-0-100’
>
> and doing the legwork of interpreting all the arguments individually (I’ve 
> seen an example of this on the web).

1. NEVER use eval().
2. Trying to pass Python code as arguments looks bad.  Don’t do that.
3. Your issues with '' are caused by your shell. You would need to
wrap your entire thing in quotes first, or use escaping. But instead,
4. Use argparse or another argument parsing solution, and implement it
with two arguments.

-- 
Chris Warrick 
PGP: 5EAAEA16
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] command line list arguments

2015-11-07 Thread Peter Otten
Garry Willgoose wrote:

> I want to input a python list as a command line argument as for example
> 
> python weathering-sens.py -daughter ['p0-50-50','p0-0-0-100’]
> 
> but what I get from sys.argv is [p0-50-50,p0-0-0-100] without the string
> delimiters on the list elements. I’m probably missing something really
> simple because sys.argv returns strings and probably strips the string
> delimiters in that conversion … but is there any way that I can keep the
> string delimiters so that inside the code I can just go (if arg is
> ['p0-50-50','p0-0-0-100’])
> 
> a=eval(arg)
> 
> or is there no alternative to doing this
> 
> python weathering-sens.py -daughter 'p0-50-50’ 'p0-0-0-100’
> 
> and doing the legwork of interpreting all the arguments individually (I’ve
> seen an example of this on the web).

With argparse it's really not that much legwork:

$ cat weathering-sens.py 
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--daughter", nargs="+")
args = parser.parse_args()
print(args.daughter)

$ python weathering-sens.py -d foo bar
['foo', 'bar']

$ python weathering-sens.py --daughter p0-50-50 p0-0-0-100
['p0-50-50', 'p0-0-0-100']

Note that args.daughter is a list of strings -- no need for eval().

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Why does this function execute before being called?

2015-11-07 Thread Chris Roy-Smith

On 07/11/15 20:18, Alan Gauld wrote:

On 07/11/15 04:34, Chris Roy-Smith wrote:


def genF(ofield): ...
 for x in range(10):



def second():
 main=Toplevel(root)
 ofield=Text(main, height=15, width=15)
 ofield.pack()
 B3=Button(main, text='exit', command=main.destroy)
 B3.pack()
 B4=Button(main, text='fill text', command=genF(ofield))


You call a function by sup[plying the parens after its name.
So the function gets called here. The normal way to circumvent
that in Tkinter is to use a lambda expression to defer execution,
like so:

B4=Button(main, text='fill text', command=lambda wgt=ofield : genF(wgt))


This certainly wasn't obvious from what I could find on the internet. 
Now I see an application for Lambda



 B4.pack()
 main.mainloop()


I'm not sure you need the second mainloop. I think the
root level mainloop will work for your window too.


Just tried out leaving this second mainloop, and every works the same. I 
had assumed I needed to create a loop the same as the top window.


Thanks for clearing up this mystery

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Why does this function execute before being called?

2015-11-07 Thread Alan Gauld

On 07/11/15 09:28, Chris Roy-Smith wrote:


B4=Button(main, text='fill text', command=lambda wgt=ofield : genF(wgt))


This certainly wasn't obvious from what I could find on the internet.
Now I see an application for Lambda


I should point out you can use a def if you prefer:

def second():
main=Toplevel(root)
ofield=Text(main, height=15, width=15)
ofield.pack()
B3=Button(main, text='exit', command=main.destroy)
B3.pack()
def genFwrapper(widget = ofield): return genF(widget)
B4=Button(main, text='fill text', command=genFwrapper)
B4.pack()


The lambda just saves a line.


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about descriptors

2015-11-07 Thread Alan Gauld

On 07/11/15 12:53, Albert-Jan Roskam wrote:

Ok, now to my question.

> I want to create a class with read-only attribute access

to the columns of a .csv file.


Can you clarify what you mean by that?
The csvreader is by definition read only.
So is it the in-memory  model that you want read-only?
Except you don't really have an in-memory model that I can see?


E.g. when a file has a column named 'a', that column should

> be returned as list by using instance.a.

That appears to be a separate issue to whether the returned
list is read-only or not? As ever the issue of dynamically
naming variables at run time and then figuring out how to
access them later raises its head. Its hardly ever a good plan.


At first I thought I could do this with the builtin 'property'

> class, but I am not sure how.

To use property I think you'd need to know the names of your
columns in advance. (Or dynamically build your classes)


I now tried to use descriptors (__get__ and __set__),
which are also used by ' property'



In the " if __name__ == '__main__'" section, [a] is supposed

> to be a shorthand for == equivalent to [b].

I have no idea what you mean by that sentence?


class AttrAccess(object):

 def __init__(self, fileObj):
 self.__reader = csv.reader(fileObj, delimiter=";")
 self.__header = self.__reader.next()
 @property
 def header(self):
 return self.__header

 def __get_column(self, name):
 return [record[self.header.index(name)] for record in self.__reader]  
# generator expression might be better here.


You should only get the index once otherwise it could add a lot of time 
for a long file(especially if there were a lot of columns)


 def __get_column(self, name):
idx = self.header.index(name)
return [record[idx] for record in self.__reader]


 def __get__(self, obj, objtype=type):
 print "__get__ called"
 return self.__get_column(obj)
 #return getattr(self, obj)

 def __set__(self, obj, val):
 raise AttributeError("Can't set attribute")


If you want everything read-only should this not be __setattr__()?


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Regarding to kivy installation

2015-11-07 Thread Laura Creighton
In a message of Sat, 07 Nov 2015 09:09:28 +0530, shubham sharma writes:
>Respected sir/madam,
>hello to all members of python.org . I had successfully downloaded kivy on
>window7 64-bit version.but when i try to install it then it show me error
>like:
> Traceback (most recent call last):
>   File "C:/Python27/kivyhello.py", line 4, in 
> from kivy.app import App
>   File "C:/Python27\kivy\app.py", line 316, in 
> from kivy.base import runTouchApp, stopTouchApp
>   File "C:/Python27\kivy\base.py", line 30, in 
> from kivy.event import EventDispatcher
>   File "C:/Python27\kivy\event.py", line 8, in 
> import kivy._event
> ImportError: DLL load failed: %1 is not a valid Win32 application.and the
>application close .
>i kindly request to all please suggest me some ways to solve it .
>Thank you

Your problem is likely that you need to set your path properly so the libraries 
can be found.
http://stackoverflow.com/questions/14629818/importerror-dll-load-failed-1-is-not-a-valid-win32-application

I am not a windows user, but
https://docs.python.org/3/using/windows.html says how you are to configure
your PATH.

And this mailing list is full of windows users, all of whom can probably
explain this a whole lot better than I, or the docs can, given that
they know this is the (likely) problem.

Laura


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about descriptors

2015-11-07 Thread Peter Otten
Albert-Jan Roskam wrote:

> 
> 
> p, li { white-space: pre-wrap; }
> 
> Hi,
> First, before I forget, emails from hotmail/yahoo etc appear to end up in
> the spam folder these days, so apologies in advance if I do not appear to
> follow up to your replies. Ok, now to my question. I want to create a
> class with read-only attribute access to the columns of a .csv file. E.g.
> when a file has a column named 'a', that column should be returned as list
> by using instance.a. At first I thought I could do this with the builtin
> 'property' class, but I am not sure how. I now tried to use descriptors
> (__get__ and __set__), which are also used by ' property' (See also:
> https://docs.python.org/2/howto/descriptor.html).
> 
> In the " if __name__ == '__main__'" section, [a] is supposed to be a
> shorthand for == equivalent to [b]. But it's not.I suspect it has to do
> with the way attributes are looked up. So once an attribute has been found
> in self.__dict__ aka "the usual place", the search stops, and __get__ is
> never called. But I may be wrong. I find the __getatttribute__,
> __getattr__ and __get__ distinction quite confusing. What is the best
> approach to do this? Ideally, the column values should only be retrieved
> when they are actually requested (the .csv could be big). Thanks in
> advance!
> 
> 
> 
> import csv
> from cStringIO import StringIO
> 
> 
> class AttrAccess(object):
> 
> 
> def __init__(self, fileObj):
> self.__reader = csv.reader(fileObj, delimiter=";")
> self.__header = self.__reader.next()
> #[setattr(self, name, self.__get_column(name)) for name in
> #[self.header]
> self.a = range(10)
> 
> 
> @property
> def header(self):
> return self.__header
> 
> def __get_column(self, name):
> return [record[self.header.index(name)] for record in
> self.__reader]  # generator expression might be better here.
> 
> def __get__(self, obj, objtype=type):
> print "__get__ called"
> return self.__get_column(obj)
> #return getattr(self, obj)
> 
> def __set__(self, obj, val):
> raise AttributeError("Can't set attribute")
> 
> if __name__ == " __main__":
> f = StringIO("a;b;c\n1;2;3\n4;5;6\n7;8;9\n")
> instance = AttrAccess(f)
> print instance.a  # [a] does not call __get__. Looks, and finds, in
> self.__dict__?
> print instance.__get__("a")  # [b] this is supposed to be equivalent
> to [a]
> instance.a = 42  # should throw AttributeError!

I think the basic misunderstandings are that 

(1) the __get__() method has to be implemented by the descriptor class
(2) the descriptor instances should be attributes of the class that is 
supposed to invoke __get__(). E. g.:

class C(object):
   x = decriptor()

c = C()

c.x # invoke c.x.__get__(c, C) under the hood.

As a consequence you need one class per set of attributes, instantiating the 
same AttrAccess for csv files with differing layouts won't work.

Here's how to do it all by yourself:

class ReadColumn(object):
def __init__(self, index):
self._index = index
def __get__(self, obj, type=None):
return obj._row[self._index]
def __set__(self, obj, value):
raise AttributeError("oops")


def first_row(instream):
reader = csv.reader(instream, delimiter=";")

class Row(object):
def __init__(self, row):
self._row = row

for i, header in enumerate(next(reader)):
setattr(Row, header, ReadColumn(i))

return Row(next(reader))


f = StringIO("a;b;c\n1;2;3\n4;5;6\n7;8;9\n")
row = first_row(f)
print row.a
row.a = 42

Instead of a custom descriptor you can of course use the built-in property:

for i, header in enumerate(next(reader)):
setattr(Row, header, property(lambda self, i=i: self._row[i]))

In many cases you don't care about the specifics of the row class and use 
collections.namedtuple:


def rows(instream):
reader = csv.reader(instream, delimiter=";")
Row = collections.namedtuple("Row", next(reader))
return itertools.imap(Row._make, reader)


f = StringIO("a;b;c\n1;2;3\n4;5;6\n7;8;9\n")
row = next(rows(f))
print row.a
row.a = 42


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about descriptors

2015-11-07 Thread Steven D'Aprano
On Sat, Nov 07, 2015 at 12:53:11PM +, Albert-Jan Roskam wrote:

[...]
> Ok, now to my question. I want to create a class with read-only 
> attribute access to the columns of a .csv file. E.g. when a file has a 
> column named 'a', that column should be returned as list by using 
> instance.a. At first I thought I could do this with the builtin 
> 'property' class, but I am not sure how. 

90% of problems involving computed attributes (including "read-only" 
attributes) are most conveniently solved with `property`, but I think 
this may be an exception. Nevertheless, I'll give you a solution in 
terms of `property` first.

I'm too busy/lazy to handle reading from a CSV file, so I'll fake it 
with a dict of columns.


class ColumnView(object):
_data = {'a': [1, 2, 3, 4, 5, 6],
 'b': [1, 2, 4, 8, 16, 32],
 'c': [1, 10, 100, 1000, 1, 10],
 }
@property
def a(self):
return self._data['a'][:]
@property
def b(self):
return self._data['b'][:]
@property
def c(self):
return self._data['c'][:]



And in use:

py> cols = ColumnView()
py> cols.a
[1, 2, 3, 4, 5, 6]
py> cols.a = []
Traceback (most recent call last):
  File "", line 1, in ?
AttributeError: can't set attribute



Now, some comments:

(1) You must inherit from `object` for this to work. (Or use Python 3.) 
It won't work if you just say "class ColumnView:", which would make it a 
so-called "classic" or "old-style" class. You don't want that.


(2) Inside the property getter functions, I make a copy of the lists 
before returning them. That is, I do:

return self._data['c'][:]

rather than:

return self._data['c']


The empty slice [:] makes a copy. If I did not do this, you could mutate 
the list (say, by appending a value to it, or deleting items from it) 
and that mutation would show up the next time you looked at the column.


(3) It's very tedious having to create a property for each column ahead 
of time. But we can do this instead:


def make_getter(key):
def inner(self):
return self._data[key][:]
inner.__name__ = key
return property(inner)


class ColumnView(object):
_data = {'a': [1, 2, 3, 4, 5, 6],
 'b': [1, 2, 4, 8, 16, 32],
 'c': [1, 10, 100, 1000, 1, 10],
 }
for key in _data:
locals()[key] = make_getter(key)
del key


and it works as above, but without all the tedious manual creation of 
property getters.

Do you understand how this operates? If not, ask, and someone will 
explain. (And yes, this is one of the few times that writing to locals() 
actually works!)


(4) But what if you don't know what the columns are called ahead of 
time? You can't use property, or descriptors, because you don't know 
what to call the damn things until you know what the column headers are, 
and by the time you know that, the class is already well and truly 
created. You might think you can do this:

class ColumnView(object):
def __init__(self):
# read the columns from the CSV file
self._data = ...
# now create properties to suit
for key in self._data:
setattr(self, key, property( ... ))


but that doesn't work. Properties only perform their "magic" when they 
are attached to the class itself. By setting them as attributes on the 
instance (self), they lose their power and just get treated as ordinary 
attributes. To be technical, we say that the descriptor protocol is only 
enacted when the attribute is found in the class, not in the instance.

You might be tempted to write this instead:

setattr(self.__class__, key, property( ... ))

but that's even worse. Now, every time you create a new ColumnView 
instance, *all the other instances will change*. They will grown new 
properties, or overwrite existing properties. You don't want that.

Fortunately, Python has an mechanism for solving this problem: 
the `__getattr__` method and friends.


class ColumnView(object):
_data = {'a': [1, 2, 3, 4, 5, 6],
 'b': [1, 2, 4, 8, 16, 32],
 'c': [1, 10, 100, 1000, 1, 10],
 }
def __getattr__(self, name):
if name in self._data:
return self._data[name][:]
else:
raise AttributeError
def __setattr__(self, name, value):
if name in self._data:
raise AttributeError('read-only attribute')
super(ColumnView, self).__setattr__(name, value)
def __delattr__(self, name):
if name in self._data:
raise AttributeError('read-only attribute')
super(ColumnView, self).__delattr__(name)



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] relative imports within a package?

2015-11-07 Thread James Hartley
The Python 3 tutorial discusses relative imports at:

https://docs.python.org/3/tutorial/modules.html#intra-package-references

I have the following directory structure for a package in development:

+ outer_package/
 + __init__.py
 + inner_package
 | + __init__.py
 | + myclass.py
 + collateral_directory
   + arbitrary_tool.py

arbitrary_tool.py needs to instantiate the class MyClass found in
myclass.py.  I have made MyClass accessible by adding the following to
inner_package/__init__.py:

from myclass import MyClass

Within arbitrary_tool.py, I have attempted the following:

from ..inner_package import MyClass

...but executing with Python 3.4 yields the following stack trace:

Traceback (most recent call last):
  File "./arbitrary_tool.py", line 5, in 
from ..inner_package import MyClass
SystemError: Parent module '' not loaded, cannot perform relative import

Suggestions on how to solve this would be most certainly welcomed!
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] relative imports within a package?

2015-11-07 Thread Steven D'Aprano
On Sat, Nov 07, 2015 at 04:09:19PM -0600, James Hartley wrote:
> The Python 3 tutorial discusses relative imports at:
> 
> https://docs.python.org/3/tutorial/modules.html#intra-package-references
> 
> I have the following directory structure for a package in development:
> 
> + outer_package/
>  + __init__.py
>  + inner_package
>  | + __init__.py
>  | + myclass.py
>  + collateral_directory
>+ arbitrary_tool.py


As shown above, "collateral_directory" is not part of the package. It is 
just a directory with stuff in it. The fact that the "stuff" happens to 
include a Python script is irrelevant.

If "arbitrary_tool.py" is actually independent of outer_package, you 
should have this layout:


+ arbitrary_tool.py
+ outer_package/
+ __init__.py
+ inner_package
| + __init__.py
| + myclass.py


where the enclosing directory is part of your PYTHONPATH. Then, in 
arbitrary_tool, you say:

from outer_package import MyClass
# assuming outer_package has already made this available

or 

from outer_package.inner_packages import MyClass
# assuming inner_package has made this available
# which you have done

or 

from outer_package.inner_package.myclass import MyClass

whichever you prefer.

If arbitrary_tool is not independent of outer_package, then you should 
convert it to a package with this layout:


+ outer_package/
+ __init__.py
+ inner_package
| + __init__.py
| + myclass.py
+ collateral_directory
  + __init__.py
  + arbitrary_tool.py


__init__.py may be an empty file, it just has to exist. Now 
collateral_directory is a sub-package, and you can do things like this:


# from outer_package.__init__
import collateral_directory.arbitrary_tool

# from inner_package.myclass (but watch out for circular imports)
from ..collateral_directory.arbitrary_tool import Spam


But if arbitrary_tool is part of the package, and it is the only file in 
collateral_directory, why mess about with a subpackage? Lay your package 
out like this:

+ outer_package/
+ __init__.py
+ arbitrary_tool.py
+ inner_package
| + __init__.py
| + myclass.py

and inside arbitrary_tool say:

from inner_package.myclass import MyClass


(P.S. this is Python, not Java. There is no requirement to put every 
class in its own file, in fact doing so is mildly discouraged. Does 
MyClass truly deserve its own file? If not, you may be able to simplify 
your package structure even more.)



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor