Declaring a class level nested class?

C

cmckenzie

Sigh, I'm using Google Groups and it seems I can't see my original
post and everyone's replies. I'm really keen to reply back, so I'll
just re-post my follow up for now and make sure I don't make a habit
of this. (I'll get a news reader) Here goes:

I agree, I'm C# and Java influenced, but I've got some messy Perl
experience too.

It was late when I posted my example, so I don't think I made my
question clear enough. I want to be able to construct a class level
class variable, so its global to the class, then reference it from a
class method. I wrote a web server that uses reflection to dynamically
load modules which are mapped to url paths. e.g. module "search.py"
maps to "search.html", etc... It all works great, but I want my
modules to be able to __init__ classes that belong to the module, then
when a request comes in and is passed to the module, I can reference
that initialized class.

The declaration of a class level nestedClass class variable is wrong,
but I was hoping someone could just say, "dummy, this is how to
declare a class variable when you can't construct it just yet", or
"you have to construct an empty version of nestedClass at the class
level, then just re-construct it with any parameters during __init__".

class module:
nestedClass

def __init__():
self.nestedClass = nested(10)
print self.nestedClass.nestedVar

def getNestedVar(self):
return self.nestedClass.nestedVar

class nested():
nestedVar = 1
def __init__(self, value):
nestedVar = value
print "Initialized..."

Thanks and sorry for double posting, it won't happen again.
 
C

cmckenzie

Sigh, I'm using Google Groups and it seems I can't see my original
post and everyone's replies. I'm really keen to reply back, so I'll
just re-post my follow up for now and make sure I don't make a habit
of this. (I'll get a news reader) Here goes:

I agree, I'm C# and Java influenced, but I've got some messy Perl
experience too.

It was late when I posted my example, so I don't think I made my
question clear enough. I want to be able to construct a class level
class variable, so its global to the class, then reference it from a
class method. I wrote a web server that uses reflection to dynamically
load modules which are mapped to url paths. e.g. module "search.py"
maps to "search.html", etc... It all works great, but I want my
modules to be able to __init__ classes that belong to the module, then
when a request comes in and is passed to the module, I can reference
that initialized class.

The declaration of a class level nestedClass class variable is wrong,
but I was hoping someone could just say, "dummy, this is how to
declare a class variable when you can't construct it just yet", or
"you have to construct an empty version of nestedClass at the class
level, then just re-construct it with any parameters during __init__".

class module:
  nestedClass

  def __init__():
     self.nestedClass = nested(10)
     print self.nestedClass.nestedVar

  def getNestedVar(self):
     return self.nestedClass.nestedVar

  class nested():
     nestedVar = 1
     def __init__(self, value):
        nestedVar = value
        print "Initialized..."

Thanks and sorry for double posting, it won't happen again.

Ok, it seems that my original post was present, just not searchable?
Forget my confusion on this. Thanks.
 
L

Lie Ryan

Sigh, I'm using Google Groups and it seems I can't see my original
post and everyone's replies. I'm really keen to reply back, so I'll
just re-post my follow up for now and make sure I don't make a habit
of this. (I'll get a news reader) Here goes:

I agree, I'm C# and Java influenced, but I've got some messy Perl
experience too.

It was late when I posted my example, so I don't think I made my
question clear enough. I want to be able to construct a class level
class variable, so its global to the class,

"global to the class" that's contradictory!
then reference it from a
class method.

I wrote a web server that uses reflection to dynamically
load modules which are mapped to url paths. e.g. module "search.py"
maps to "search.html",

Be careful of someone requesting an ../insecure.html
etc... It all works great, but I want my
modules to be able to __init__ classes that belong to the module, then
when a request comes in and is passed to the module, I can reference
that initialized class.

When a module is "import"-ed, it's body is executed, unless you put it
inside a if __name__ == '__main__': block which is only executed when
the module itself is executed (instead of being imported). Basically,
the module's body is like the module's __init__()

That way if your directory is like this:
/data
- /__init__.py
- /one.py
/run_server.py

your one.py would contains something like:

class MyClass(object):
...
instance = MyClass()


and your run_server.py would reference the already instantiated module
in the class as such:

from data.one import instance

# serve something using the instance



The declaration of a class level nestedClass class variable is wrong,
but I was hoping someone could just say, "dummy, this is how to
declare a class variable when you can't construct it just yet",


or
"you have to construct an empty version of nestedClass at the class
level, then just re-construct it with any parameters during __init__".

That sounds like C/C++ forward declaration. Not something you'd need in
a language that has dynamic name resolution.
 
S

Steven D'Aprano

It was late when I posted my example, so I don't think I made my
question clear enough. I want to be able to construct a class level
class variable, so its global to the class, then reference it from a
class method.

My brain is spinning, because you seem to be using terms in ways that
aren't common in Python circles (or at least not familiar to *me*). This
makes it really hard for me to be sure I understand you.

You say you want a "class level class variable" -- what do you mean by
that? What's "class level" mean to you? When you say "class variable", do
you mean "a variable that is a class", like a string variable is a
variable that is a string, or do you mean an attribute of the class?

What do you mean by "global to the class"?


In your code sample, you say:

class module:
nestedClass

but nestedClass isn't defined. Assuming nestedClass already exists,
defined elsewhere (which implies it is NOT nested at all!) it would be
syntactically legal, but meaningless. It would be as pointless as this:

class module: # Define class
[1, 2, 3] # create a list and throw it away immediately

Where is nestedClass defined? Outside the class "module"? Inside the
class? If so, where?

I *think* you mean you want a class attribute which happens to hold a
class, which you want to be nested, but I'm not sure. If that's what you
want, you would write it like this:

class module:
# Horrible name, because module is a term already
# used in Python for something else

class nestedclass:
pass

Once you do that, you have a class "module" containing a nested class
"nestedclass" which is available as a class-attribute
"module.nestedclass".

The declaration of a class level nestedClass class variable is wrong,
but I was hoping someone could just say, "dummy, this is how to declare
a class variable when you can't construct it just yet",

Python doesn't need declarations. If you can't declare something, don't.
You could put a placeholder and test for it:

class K:
attribute = None # Placeholder for the real value.
def method(self):
if self.attribute is None:
print "attribute not initialised yet, this design sucks"
else:
print "do something useful"

or simply catch the AttributeError:

class K:
def method(self):
try:
self.attribute
except AttributeError:
print "attribute not initialised yet, this design sucks"
else:
print "do something useful"

or "you have to
construct an empty version of nestedClass at the class level, then just
re-construct it with any parameters during __init__".

class module:
nestedClass

def __init__():
self.nestedClass = nested(10)
print self.nestedClass.nestedVar


That gives every instance of "module" its own instance-level attribute
called "nestedClass".

It will only work if nested is a global-level function. To call the
method called "nested" as you probably intend, you need to do this:

def __init__():
self.nestedClass = self.nested(10)
print self.nestedClass.nestedVar

which still makes nestedClass an attribute on the instance, not the
class. To make it a class attribute, you have to refer to the class
directly. Either of these will do, although the first is better because
it will do the right thing if you subclass:

self.__class__.nestedClass = self.nested(10)
module.nestedClass = self.nested(10)

class nested():
nestedVar = 1
def __init__(self, value):
nestedVar = value
print "Initialized..."


Given that every instance is given an attribute nestedVar, what's the
point of the class attribute "nestedVar"? It's never used.
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top