Python3
Tried to found an answer but failed. First I'll present the snippet, then I'll explain why I wanted to do it this way and what I wanted to achieve. Maybe it'll look like this approach is "the bad one". Hence this semi-double topic, cause first I'd like to know why this snippet isn't working and second - I'd like to know if this approach is right.
So:
class Namespace:
def some_function():
pass
class SomeClass:
fcnt = some_function
This won't work due to:
NameError: name 'some_function' is not defined
What I want to achieve is code and file structure readability.
Above example is a snippet which I use (not this one, but it looks like this) in Pyramid project.
My project tree looks like this:
my_project
├── models
│ ├── __init__.py
│ └── some_model.py
├── schemas
│ ├── __init__.py
│ ├── some_schema.py
│ └── some_other_schema.py
...
├── views
│ ├── __init__.py
│ └── some_view.py
└── __init__.py
What I wanted to achieve is clean schema/model/view importing.
In some_schema.py file resides class SomeSchema
, in some_other_schema.py class SomeOtherSchema
.
With above snippet I can make:
from my_project.schemas.some_schema import Schema
and use it like Schema.SomeSchema()
I've got a little bit lost with packages and import
s. How one could make a clean structure (one schema per file) and still be able to use Schema namespace? (In C++ I'd just put each of those classes in Schema
namespace, that's why I did this in snippet above. But! What works in C++ maybe shouldn't be used in python, right?).
Thanks for answer in advance.
EDIT: Ok, I've done some testing (I thought that I've done it, but looks like not..).
- using
from my_project.schemas.some_schema import Schema
with anotherfrom my_project.schemas.some_other_schema import Schema
causes in the second import shadowing first one. So if after first import I'd be able to usex = Schema.SomeSchema()
than after second import I'd be unable to do this, becauseclass Schema
gets overriden. Right, so as Erik said - classes aren't namespaces. GOT IT! in my very first snippet yes, I should've used
fnct = Namespace.some_function
. What's wierd - it works. I have the same statement in my pyramid code, with one difference.some_function
has@colander.deferred
decorator. In fact it looks like this:class Schema: @colander.deferred def deferred_some_function(node, kw): something = kw.get("something", []) return deform.widget.SelectWidget(values=something, multiple=True) class SomeSchema(colander.MappingSchema): somethings = colander.SchemaNode(colander.Set(), widget=Schema.deferred_some_function)
And I get
NameError: name 'Schema' is not defined
Getting back to package format. With this:
### another/file.py from foo.bar.schema import SomeSchema # do something with SomeSchema: smth = SomeSchema() smth.fcnt()
I have to make one module
foo/bar/schema.py
in which I'd have to put all mySomeXSchema
classes. An if I have lots of them, then there's the unreadabilty glitch which I wanted to get rid off by splitting SomeXSchema - one per file. Can I accomplish this somehow? I want to call this class for example:User
. And here's the THING. Maybe I do it wrong? I'd like to have class namedUser
inschema
namespace and class namedUser
inmodel
namespace. Shouldn't I? Maybe I ought to use prefix? Likeclass SchemaUser
andclass ModelUser
? I wanted to avoid it by the use of modules/packages. If I'd use :import foo.bar.schema
then I'd have to use it likex = foo.bar.schema.User()
right? There is no way to use it likex = schema.User()
? Sorry, I just got stuck, my brain got fixed. Maybe I need a little break to take a fresh look?ANOTHER EDIT (FOR POINT 3 ONLY)
I did some more research. The answer here would be to make it like this:
## file: myproject/schemas/__init__.py from .some_schema import SomeSchema from .some_other_schema import SomeOtherSchema
then usage would be like this:
## some file using it import myproject.schemas as schema s1 = schema.SomeSchema() s2 = schema.SomeOtherSchema()
Would it be lege artis?
If anyone thinks that topic should be changed - go ahead, give me something more meaningful, I'd appreciate it.