How to import only one module in a package when the package__init__.py has already imports the modul

P

Peng Yu

I have the following files, which are in the directory 'test'. The
parent directory of 'test' is in $PYTHONPATH. I have 'from A import A'
and 'from B import B' in '__init__.py', because I want to use 'test.A'
and 'test.B' to refer to classes A and B rather than 'test.A.A' and
'test.B.B'.

$ll -g
total 24
-rw-r--r-- 1 staff 32 2009-10-31 10:41:47 __init__.py
-rw-r--r-- 1 staff 235 2009-10-31 10:45:24 __init__.pyc
-rw-r--r-- 1 staff 550 2009-10-31 10:45:24 B.pyc
-rw-r--r-- 1 staff 550 2009-10-31 10:45:24 A.pyc
-rw-r--r-- 1 staff 54 2009-10-31 10:46:03 A.py
-rw-r--r-- 1 staff 54 2009-10-31 10:46:14 B.py
$cat __init__.py
from A import A
from B import B
$cat A.py
class A:
def __init__(self):
print '__init__ A'
$cat B.py
class B:
def __init__(self):
print '__init__ B'


Then I have the following python files to call the modules. However,
because I have 'import A from A' in '__init__.py', I can not call
'test.A.A()' anymore. Even I only have 'import test.A', both modules
'A' and 'B' are imported. So 'import test.A' is essentially the same
as 'import test'.

I'm wondering if there is a way to make the following two things hold.
Thank you1
1. When I 'import test', I can refer to class A as 'test.A'.
2. When I 'import test.A', I can refer to class A as 'test.A.A' and
class B shall not be imported.



$cat fail.py
import test.A
test.A.A()
$python fail.py
Traceback (most recent call last):
File "fail.py", line 2, in <module>
test.A.A()
AttributeError: class A has no attribute 'A'
$cat main.py
import test
test.A()
test.B()
$python main.py
__init__ A
__init__ B
$cat fail2.py
import test.A
test.A()
test.B()
$python fail2.py
__init__ A
__init__ B
 
P

Peng Yu

No. Either import adds the name 'test' to the current namespace. That name
in each case references the same thing.

Your simplest solution would be to give the sub-modules lowercase
filenames, then you can do:

  import test
  test.A()

or

  import test.a
  test.a.A()

or even

  import test.a
  test.b.B()

It would probably be best though just to be consistent as to how you
reference the classes: define a public interface for your package and stick
to it.

The original problem comes from the maintenance of the package. When A
and B are large classes, it is better to put them in separate files
under the directory 'test' than put them in the file 'test.py'. The
interface 'test.A' is used by end users. However, there will be a
problem if 'import test' is used for developers, because both A and B
are imported, which cause dependence between A and B. For example,
during the modification of B (not finished), 'import A' would not
work. This is means that modifications of A and B are not independent,
which cause a lot of problem when maintaining the package.

Naming the filename different from the class is a solution, but it is
a little bit annoying.

I'm wondering how people handle this situation when they have to
separate a module into multiple modules.
 
R

Robert Kern

The original problem comes from the maintenance of the package. When A
and B are large classes, it is better to put them in separate files
under the directory 'test' than put them in the file 'test.py'. The
interface 'test.A' is used by end users. However, there will be a
problem if 'import test' is used for developers, because both A and B
are imported, which cause dependence between A and B. For example,
during the modification of B (not finished), 'import A' would not
work. This is means that modifications of A and B are not independent,
which cause a lot of problem when maintaining the package.

To be frank, that development process is going to cause you a lot of problems
well beyond these import entanglements. Developers should have their own
workspace! They shouldn't push things into production until the system is
working. Checking something into source control shouldn't automatically deploy
things into production.
Naming the filename different from the class is a solution, but it is
a little bit annoying.

I'm wondering how people handle this situation when they have to
separate a module into multiple modules.

Even if we organize things along the lines of "one class per module", we use
different capitalization conventions for modules and classes. In part, this
helps solve your problem, but it mostly saves the developer thought-cycles from
having to figure out which you are referring to when reading the code.

Personally, I like to keep my __init__.py files empty such that I can import
exactly what I need from the package. This allows me to import exactly the
module that I need. In large packages with extension modules that can be
expensive to load, this is useful. We usually augment this with an api.py that
exposes the convenient "public API" of the package, the A and B classes in your
case.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
W

Wolodja Wentland

[ snip ]
I know that multiple classes or functions are typically defined in one
file (i.e. module in python). However, I feel this make the code not
easy to read. Therefore, I insist on one class or function per file
(i.e module in python).

Are you serious? Do you *really* put each function in its own file? How
exactly does this enhance the readability of the source code? Especially
if you compare that to a (sic!) modularisation scheme that groups
classes and functions together by task or semantic relatedness.

regards

Wolodja

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iQIcBAEBCAAGBQJK7L38AAoJEIt/fTDK8U78Pv4P/icEwsmSLcuINWZHj4Shs0A/
1/TZcuP5VwuR6gZ0WsywKzbKJqL0WDahUi4o3VkwFuM2mKskXzch3buZ5NvlwOp6
I+NqBn9jCTb3nXiVb5wHdF6uYf84BPZe1WccRIDJLIoGRWX/V6tmMH1LtLGnBeVi
RGOd6Mz2KGr1cgisyYJ2h4Qm5tzKNuZ1KDtzXoOG4DYzwEEZBITFOwDNXy5tihJz
v/NcAZOa4aBfJZtKxA7Ikl+30nDV8ZZhEU7Br/rIus2JrSqMp6gAh4f+zTz9jQzL
Sp7O3bTQiHoghej+G4YW+/eMDTiNDSKm1u8++V5svwednp/mmYBnzA8aIPKFSoN6
vn4D0Q2XVGQAoWyY7pT9zyRKBJnn63xXD5h9T6JimEz7uMWGzTebIuxFRHsd1vkt
TYTW1kJDH8aIsy51egBezZx8o6sntBFu3D+D3itqDW2D2sZ75sPiblgkLCWHvZMR
RaBjCkvhVjOaiJOZ64mRmkW3RUJzY6lGvEqfQqW1bRpHxLEUKaWLy6rWa0sQTTut
rIZ/5TdnjPec1Dx+9v6V7sW8bZtCttpb7j4k+DBAMjRpW7mocnGfuxGN/57Y/uD0
gFOURpMz1rjEdPCiYZuUQX+joS3tl9IxnBZL7gTRl3slSWoVlGuhcqsew3nAkrGB
Fx8iwKUAwwRULxzigHHB
=n3s3
-----END PGP SIGNATURE-----
 
R

Robert Kern

I don't quite agree with your opinion. But please don't take it too personaly.

Even in the developer's work space, it is possible to change multiple
classes simultaneously. So the import entanglement problem still
exists.

But it's a problem that should have different consequences than you are
claiming. Having users prevented from using A because developers are modifying
their copy of B in production is a problem that needs to be solved by changing
your development process. If you don't change your development process, you will
run into the same problems without import entanglements.

Now as to import entanglements in the developer's workspace, it is true that
they can cause issues from time to time, but they are much, much smaller in
practice. I can just go in and comment out the offending import temporarily
while I finish working on the other part until I'm ready to address both of them
together. Then when I'm finished and things are working again, I can check my
code into source control. It's just not a big deal.
I know that multiple classes or functions are typically defined in one
file (i.e. module in python). However, I feel this make the code not
easy to read. Therefore, I insist on one class or function per file
(i.e module in python).

One function per file is a little extreme. I am sympathetic to "one class per
module", but functions *should* be too short too warrant a module to themselves.
When one class per module is strictly enforced, there will be no need
to have different capitalization conventions for modules and classes.
Developers should be able to tell whether it is a class or a module
from the context.

Given enough brain-time, but you can make your code easier to read by using
different conventions for different things. Developer brain-time is expensive!
As much as possible, it should be spent on solving problems, not comprehension.
In my question, module A and B exist just for the sake of
implementation. Even if I have module A and B, I don't want the user
feel the existence of module A and B. I want them feel exact like
class A and B are defined in module 'test' instead of feeling two
modules A and B are in package 'test'. I know that module names should
be in lower cases, in general. However, it is OK to have the module
name capitalized in this case since the end users don't see them.

In C++, what I am asking can be easily implemented, because the
namespace and the directory hierachy is not bind to each other.
However, the binding between the namespace and the directory hierachy
make this difficult to implement. I don't know if it is not
impossible, but I'd hope there is a way to do so.

I'm not sure that C++ is a lot better. I still have to know the file hierarchy
in order to #include the right files. Yes, the namespaces get merged when you go
to reference things in the code, but those #includes are intimately tied to the
file hierarchy.

In C++, you can often #include one file that #includes everything else because
linking won't bring in the symbols you don't actually use. Oddly enough, we
don't have that luxury because we are in a dynamic language. Python imports have
runtime consequences because there is no compile or link step. You can't think
of import statements as #include statements and need to use different patterns.

Of course, to really take advantage of that feature in C++ requires some careful
coding and use of patterns like pimpl. That often negates any readability benefits.

You could probably hack something (and people have), but it makes your code
harder to understand because it is non-standard.
I looked at python library, there are quite a few __init__.py files
are not empty. In fact, they are quite long. I agree with you that
'__init__.py' should not be long. But I'm wondering why in python
library __init__.py are quite long.

For the most part, it's just not an issue. If you are seeing serious problems,
this may just be exposing deeper issues with your code and your process that
will come to bite you in other contexts sooner or later.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
P

Peng Yu

[ snip ]
I know that multiple classes or functions are typically defined in one
file (i.e. module in python). However, I feel this make the code not
easy to read. Therefore, I insist on one class or function per file
(i.e module in python).

Are you serious? Do you *really* put each function in its own file? How
exactly does this enhance the readability of the source code? Especially
if you compare that to a (sic!) modularisation scheme that groups
classes and functions together by task or semantic relatedness.

If two functions are too long to put in file, I generally put them in
two different files. And I always put a single class in a file.
Suppose that I have many functions in one file, it is not clear to see
how many functions are in the file at first glance. If I put each
function in its own file, just by looking at the directory structure,
I can easily see how many functions there are.

One advantage is on refactoring. When each function has its own file,
I can change variable names, etc., for a give function without
worrying accidentally change variable names in other functions. When I
find a function is more appropriate to put in another namespace, I can
just move the file around.

Another advantage is on testing. I can have associated test dir for
each class or function. By this way I can easily locate the definition
and the test to track any potential problems.

You can use package rather than module to group semantic related
classes and functions.
 
W

Wolodja Wentland

If two functions are too long to put in file, I generally put them in
two different files.

If it should ever happen that two functions are too long to put in a
single file you should refactor your code. It is usually a good idea of
breaking problems down into single steps (ie functions) so you never end
up with a 5000 SLOC *function*.

How do functions of this length enhance the readability of your source
code?
And I always put a single class in a file.

Why? What do you gain by that?
Suppose that I have many functions in one file, it is not clear to see
how many functions are in the file at first glance.

Use a better editor/IDE for that.

[snip]

I thought about answering your post in greater detail, but i would like
to evaluate your style of work first. Is there any place where I can
have a look at some of your source code? It would be perfect if it is a
medium sized project with said unit tests, packages and
function-modules and the rest you described.

Why does not a single module in in the stdlib follow your code layout
scheme?

regards

Wolodja

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iQIcBAEBCAAGBQJK7NSXAAoJEIt/fTDK8U78EvAP/2SGRm/FxnoSw1jr3MDxc4Gp
Y8RichWXliSjGcRXKw5R3pk2SkAkmmCW0TgR2Pxn75hTi9XQ5KOTXgGNKMQVeYox
QtejLw2e1ITPwd1dT/dkZQdfzL7jpdtvsod+uv0gPTcbTlwmyRnveneA1v0gBw2U
tlHz5VeCaK3cakvQBunESnz3lcnpt1uMMrG7ZRhweAsV2mB2quEZGmDt+6FfcL7g
M7wavW7EfNbdCa882oGzqgbZtY526tDkm+u478eObTx4MkFDo5ERkVBAU0KpoPwR
mU7/FYnvv+ergy7U9HVAtQy2uQNABVaN6qDl025YqsCXmcJCf+JiunE+HhOR96LZ
fr08p8MjP3n/enhKXizRuc904xljSh2D7eWo/SWy0mkP87BRw657bIJl1S6vG28Q
qvTc/ke6lxvRRtSMjeRDLCQJuco6DpN6chD88ZA0L8sJwBaUsQeUBBXF8j2yfza/
pn2AZ5H+CZVeX59md35U9yyZnrkASoMP6bYbEUROAWZDQV+Nvb00itAwhagPGHwC
pnMk+ALjWpMa8ltwGFt9jGFDfmNNhiL69i/vhVV4d8oGqv4k3YjxqCzMAGYGGluR
cMN/HowHPhCY+ZbCiDwbY1wsnfGlnPXZqtnC92evmGQBXJtcwdRtMLM+wMvDKgeW
L4mk6Iu8vhAaS9KEu2C4
=8V6q
-----END PGP SIGNATURE-----
 
R

Robert Kern

Why? What do you gain by that?

While it's never a good idea to follow the rule slavishly, it's often a good
idea. Many classes are themselves a semantic unit of functionality enough to
justify their own module. I've certainly seen the rule overapplied, though.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
P

Peng Yu

If it should ever happen that two functions are too long to put in a
single file you should refactor your code. It is usually a good idea of
breaking problems down into single steps (ie functions) so you never end
up with a 5000 SLOC *function*.

My definition of long is more than one screen.
How do functions of this length enhance the readability of your source
code?

If the code is of one screen, you can easily see what it does without
having to scroll back and forth.
Why? What do you gain by that?

It makes me easier to look for an class. I can just search the
filename to get a class. By looking at the packages imported in the
file, I can easily see what packages a class depends. If there are
multiple classes in a file, I will not know which packages a class
actually depends on.
Use a better editor/IDE for that.

What editor you use? I use vim. I'm sure there is a way to configure
vim to fold the definition of a class. But I don't use it because I
feel folding and unfolding code is not convenient.
[snip]

I thought about answering your post in greater detail, but i would like
to evaluate your style of work first. Is there any place where I can
have a look at some of your source code? It would be perfect if it is a
medium sized project with said unit tests, packages and
function-modules and the rest you described.

I just started writing python code. So I don't have much code to show
you now. But I have written a project of 25,000 lines of code in C++.
In this project, I always have a file for a class. My directory
structure looks like the following (toward the end). But having this
structure it is every easy to navigate to any class or function.
Please let me know if you need any more information.

src/ has all the source code and testing code. Because I usually need
to change source code and the corresponding test code at the same
time, I put them close to each other.

include/ has links to all the header files and maintains the directory
structure (include/ is generated automatically based on the content of
src/). All .cpp files are linked to lib/, where the library file is
made.

The unit test for divide is in main.cpp.
| |-- divide.cpp
| |-- divide.hpp
| `-- main.cpp

When test cases become big, I separate them into multiple main.cpp
files like below.
| |-- half
| | |-- Makefile
| | |-- cap
| | | |-- Makefile
| | | `-- main.cpp
| | |-- half.hpp
| | |-- is_interleaved
| | | |-- Makefile
| | | `-- main.cpp
| | |-- less_than
| | | |-- Makefile
| | | `-- main.cpp
| | `-- main
| | |-- Makefile
| | `-- main.cpp

The namespace is defined accordingly. For example, class divide.hpp is
in numerical/divide.hpp, therefore, I use numerical::divide to refer
it.

### example directory structure
..
|-- include
| `-- numerical
| |-- divide.hpp -> ../../src/divide/divide.hpp
| |-- interval
| | |-- combine_half.hpp ->
.../../../src/interval/combine_half/combine_half.hpp
| | |-- half.hpp -> ../../../src/interval/half/half.hpp
| | |-- linear.hpp -> ../../../src/interval/linear/linear.hpp
| | `-- rotated.hpp -> ../../../src/interval/rotated/rotated.hpp
| `-- smart_increment.hpp -> ../../src/smart_increment/smart_increment.hpp
|-- lib
| |-- Makefile
| |-- libnumerical.so -> libnumerical.so.1
| |-- libnumerical.so.1 -> libnumerical.so.1.0.0
| `-- numerical
| `-- divide.cpp -> ../../src/divide/divide.cpp
`-- src
|-- Makefile
|-- divide
| |-- Makefile
| |-- divide.cpp
| |-- divide.hpp
| `-- main.cpp
|-- interval
| |-- Makefile
| |-- combine_half
| | |-- Makefile
| | |-- combine_half.hpp
| | `-- main.cpp
| |-- half
| | |-- Makefile
| | |-- cap
| | | |-- Makefile
| | | `-- main.cpp
| | |-- half.hpp
| | |-- is_interleaved
| | | |-- Makefile
| | | `-- main.cpp
| | |-- less_than
| | | |-- Makefile
| | | `-- main.cpp
| | `-- main
| | |-- Makefile
| | `-- main.cpp
`-- smart_increment
|-- Makefile
|-- main.cpp
`-- smart_increment.hpp
 
D

Dave Angel

Peng said:
[ snip ]

I know that multiple classes or functions are typically defined in one
file (i.e. module in python). However, I feel this make the code not
easy to read. Therefore, I insist on one class or function per file
(i.e module in python).
Are you serious? Do you *really* put each function in its own file? How
exactly does this enhance the readability of the source code? Especially
if you compare that to a (sic!) modularisation scheme that groups
classes and functions together by task or semantic relatedness.

<snip>
One advantage is on refactoring. When each function has its own file,
I can change variable names, etc., for a give function without
worrying accidentally change variable names in other functions. When I
find a function is more appropriate to put in another namespace, I can
just move the file around.
Variables in a function are already private. How can the names in one
function be affected by other functions in the same module?

DaveA
 
S

Steven D'Aprano

If two functions are too long to put in file, I generally put them in
two different files.

If two functions are too long for a single file, the functions are too
big and need to be broken up into ten or thirty sub-functions each!

Ideally, no function should be more than ten or twenty lines (plus
docstring), certainly no more than a page. In a language like Python that
is so compact, monster functions that are hundreds of lines long is
almost certainly inexcusable.

And I always put a single class in a file.

An unnecessary and silly restriction. It is reasonable for large
complicated classes, but not a rule for all classes, some of which might
be as small as two lines.

Suppose that I have many functions in one file, it is not clear to see
how many functions are in the file at first glance.

So what? Why is it import to see how many functions are in the file?


If I put each function in its
own file, just by looking at the directory structure, I can easily see
how many functions there are.

Why do you care how many functions there are?

One advantage is on refactoring. When each function has its own file, I
can change variable names, etc., for a give function without worrying
accidentally change variable names in other functions.

Do you understand that each function has it's own local namespace? Unless
you are foolish enough to use global variables for everything, you can
refactor any given function without effecting other functions in the same
file.

When I find a
function is more appropriate to put in another namespace, I can just
move the file around.

A module is a namespace.

Another advantage is on testing. I can have associated test dir for each
class or function. By this way I can easily locate the definition and
the test to track any potential problems.

You can do this when functions share the same file.

You can use package rather than module to group semantic related classes
and functions.

Python makes available many namespaces:

Function
Module
Package

You are artificially restricting yourself to use:

Function = Module
Package

and that's supposed to be an advantage???
 
S

Steven D'Aprano

My definition of long is more than one screen.


If the code is of one screen, you can easily see what it does without
having to scroll back and forth.

Far enough, but you exchange scrolling back and forth from function to
function with tabbing through editor tabs from file to file. I don't see
that this is an advantage.

You also complicate calling functions. Instead of:


def parrot():
spam()
ham()
cheeseshop()


you need:


from spam import spam
from ham import ham
from import cheeseshop

def parrot():
spam()
ham()
cheeseshop()


This is not an advantage!
 
S

Steven D'Aprano

I know that multiple classes or functions are typically defined in one
file (i.e. module in python). However, I feel this make the code not
easy to read. Therefore, I insist on one class or function per file (i.e
module in python).

When one class per module is strictly enforced, there will be no need to
have different capitalization conventions for modules and classes.
Developers should be able to tell whether it is a class or a module from
the context.

Classes and modules are first-class objects in Python, so you can't
necessarily tell what they are from context. I frequently have code like
this:


def verify(test_func, objects_to_process, expected_results):
for obj, result in zip(objects_to_process, expected_results):
print "Testing %r..." % obj,
r = test_func(obj)
if r == result:
print "verified"
else:
print "expected %r but got %s" % (result, r)


objects_to_process could be a list of floats, strings, functions,
modules, or anything else. Having a naming convention is still useful for
distinguishing (say) factory functions from classes, or modules from
classes.

In my question, module A and B exist just for the sake of
implementation. Even if I have module A and B, I don't want the user
feel the existence of module A and B. I want them feel exact like class
A and B are defined in module 'test' instead of feeling two modules A
and B are in package 'test'.


Inside test/__init__.py:

from A import A # class A from file A.py
from B import B # class B from file B.py


or better still:

from a import A # class A from file a.py
from b import B # class B from file b.py


I know that module names should be in lower
cases, in general. However, it is OK to have the module name capitalized
in this case since the end users don't see them.

Of course they do.


I looked at python library, there are quite a few __init__.py files are
not empty. In fact, they are quite long. I agree with you that
'__init__.py' should not be long. But I'm wondering why in python
library __init__.py are quite long.

Define "quite long".

In Python 2.6, I have:

[steve@sylar python2.6]$ for file in */__init__.py; do echo "$file" `cat
$file | wc -l` ; done
bsddb/__init__.py 450
compiler/__init__.py 29
ctypes/__init__.py 546
curses/__init__.py 59
distutils/__init__.py 26
email/__init__.py 123
encodings/__init__.py 157
hotshot/__init__.py 78
idlelib/__init__.py 1
json/__init__.py 318
lib2to3/__init__.py 1
logging/__init__.py 1490
multiprocessing/__init__.py 271
sqlite3/__init__.py 24
test/__init__.py 1
wsgiref/__init__.py 23
xml/__init__.py 47



With the exception of logging, I don't see any of those as quite long.
 
P

Peng Yu

Classes and modules are first-class objects in Python, so you can't
necessarily tell what they are from context. I frequently have code like
this:


def verify(test_func, objects_to_process, expected_results):
   for obj, result in zip(objects_to_process, expected_results):
       print "Testing %r..." % obj,
       r = test_func(obj)
       if r == result:
           print "verified"
       else:
           print "expected %r but got %s" % (result, r)

This example doesn't invalidate my statement. When I say "Developers
should be able to tell whether it is a class or a module from the
context", I mean the case of defining them or creating objects. In the
above case, you still can enforce one class/function per module.
objects_to_process could be a list of floats, strings, functions,
modules, or anything else. Having a naming convention is still useful for
distinguishing (say) factory functions from classes, or modules from
classes.




Inside test/__init__.py:

from A import A  # class A from file A.py
from B import B  # class B from file B.py

I can not use the above approach as I mentioned its problem in my
previous message.
or better still:

from a import A  # class A from file a.py
from b import B  # class B from file b.py

This artificially introduces the constraint that the file name can not
be the same as the class/function name. There is no constraint like
this if I can C++.
Of course they do.

This sentence is confusing. Can you spell out what you mean?
I looked at python library, there are quite a few __init__.py files are
not empty. In fact, they are quite long. I agree with you that
'__init__.py' should not be long. But I'm wondering why in python
library __init__.py are quite long.

Define "quite long".

In Python 2.6, I have:

[steve@sylar python2.6]$ for file in */__init__.py; do echo "$file" `cat
$file | wc -l` ; done
bsddb/__init__.py 450
compiler/__init__.py 29
ctypes/__init__.py 546
curses/__init__.py 59
distutils/__init__.py 26
email/__init__.py 123
encodings/__init__.py 157
hotshot/__init__.py 78
idlelib/__init__.py 1
json/__init__.py 318
lib2to3/__init__.py 1
logging/__init__.py 1490
multiprocessing/__init__.py 271
sqlite3/__init__.py 24
test/__init__.py 1
wsgiref/__init__.py 23
xml/__init__.py 47



With the exception of logging, I don't see any of those as quite long.

I have defined 'long' in one of my previous message. I consider a file
long, when it does not fit in one or two screen. Basically, I want to
get a whole picture of the file after glancing of the file.
 
P

Peng Yu

Far enough, but you exchange scrolling back and forth from function to
function with tabbing through editor tabs from file to file. I don't see
that this is an advantage.

You also complicate calling functions. Instead of:


def parrot():
   spam()
   ham()
   cheeseshop()


you need:


from spam import spam
from ham import ham
from import cheeseshop

def parrot():
   spam()
   ham()
   cheeseshop()


This is not an advantage!

I would say this is the disadvantage of python, if there is no
walkaround to avoid using 'from spam import spam'. As this can be
handled in C++ with walkaround.

So far the best solution is:

Inside test/__init__.py:

from a import A # class A from file a.py
from b import B # class B from file b.py

However, this is not satisfactory enough because this artificially
introduces the constraint that the file name can not be the same as
the class/function name.
 
R

Robert Kern

Peng said:
I have defined 'long' in one of my previous message. I consider a file
long, when it does not fit in one or two screen. Basically, I want to
get a whole picture of the file after glancing of the file.

I think you are going to have to get used to the fact that you have very strange
personal preferences and that Python is designed for the vast majority of
programmers who do not share them.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
P

Peng Yu

If two functions are too long for a single file, the functions are too
big and need to be broken up into ten or thirty sub-functions each!

Ideally, no function should be more than ten or twenty lines (plus
docstring), certainly no more than a page. In a language like Python that
is so compact, monster functions that are hundreds of lines long is
almost certainly inexcusable.



An unnecessary and silly restriction. It is reasonable for large
complicated classes, but not a rule for all classes, some of which might
be as small as two lines.



So what? Why is it import to see how many functions are in the file?




Why do you care how many functions there are?

Because I want to easily see what functions are there.
Do you understand that each function has it's own local namespace? Unless
you are foolish enough to use global variables for everything, you can
refactor any given function without effecting other functions in the same
file.



A module is a namespace.

This is a constrain imposed by python. C++ does not have this
constraint, so I can have each class in a file without any
complication in calling classes.

Because of this constraint in python. I have do something

from spam import spam

or

call spam.spam.
You can do this when functions share the same file.



Python makes available many namespaces:

Function
Module
Package

You are artificially restricting yourself to use:

Function = Module
Package

and that's supposed to be an advantage???

Since Module = file, by making Function = Module and Class = Module,
it simplifies the search of a function and a class. I also put the
testing code along with the module, which make it easier to move
module across packages (when I do refactoring, sometime I found some
module is not appropriate to put in a package anymore, so I need to
move it to a better package).
 
P

Peng Yu

Peng said:
On Sat, Oct 31, 2009 at 16:53 -0500, Peng Yu wrote:


[ snip ]



I know that multiple classes or functions are typically defined in one
file (i.e. module in python). However, I feel this make the code not
easy to read. Therefore, I insist on one class or function per file
(i.e module in python).


Are you serious? Do you *really* put each function in its own file? How
exactly does this enhance the readability of the source code? Especially
if you compare that to a (sic!) modularisation scheme that groups
classes and functions together by task or semantic relatedness.

<snip>
One advantage is on refactoring. When each function has its own file,
I can change variable names, etc., for a give function without
worrying accidentally change variable names in other functions. When I
find a function is more appropriate to put in another namespace, I can
just move the file around.

Variables in a function are already private.  How can the names in one
function be affected by other functions in the same module?

You misunderstood me.

If there are multiple functions or classes in a file, when I change
variables in a function/class, I have to make sure that they are not
in other functions or classes. This makes the refactoring process
tedious. If I have a single class/function in a file, I can safely
change variable names without worrying broken other classes or
functions.
 
P

Peng Yu

I think you are going to have to get used to the fact that you have very
strange personal preferences and that Python is designed for the vast
majority of programmers who do not share them.

So python would not be able to accommodate my preference one
class/function per file? I.e., I have to use something like 'from spam
import spam' or 'spam.spam()', or accept that the filename is not the
same as the class/function name.

Inside test/__init__.py:
from a import A # class A from file a.py
from b import B # class B from file b.py
 
R

Robert Kern

Peng said:
So python would not be able to accommodate my preference one
class/function per file? I.e., I have to use something like 'from spam
import spam' or 'spam.spam()', or accept that the filename is not the
same as the class/function name.

Inside test/__init__.py:
from a import A # class A from file a.py
from b import B # class B from file b.py

If you are going to expose symbols in your __init__.py, they should not have the
same name as any of the modules in the package.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top