Is this type of forward referencing possible?

  • Thread starter Kooks are people too
  • Start date
K

Kooks are people too

If I try this:

class A:
someType = B

class B:
anotherType = A

I get:
<type 'exceptions.NameError'>: name 'B' is not defined
args = ("name 'B' is not defined",)
message = "name 'B' is not defined"

Presumably because I'm instantiating an instance of a type object (B)
that doesn't exist yet.

Is there any way to do this?

Why I'd want to do this actually has to do with Google's datastore
api. I'm doing something similar to this:

from google.appengine.ext import db

class A:
aB = db.ReferenceType(B)

class B:
anA = db.ReferenceType(A)
 
L

Lawrence D'Oliveiro

In message <a96e95ab-9953-4e61-
If I try this:

class A:
someType = B

class B:
anotherType = A

I get:
<type 'exceptions.NameError'>: name 'B' is not defined
args = ("name 'B' is not defined",)
message = "name 'B' is not defined"

Try

class A:
pass
class B:
anotherType = A
A.someType = B
 
P

Paul McGuire

someone else has answered this, but an extra trick that is sometimes
useful is that while there is no forward referencing you can often exploit
late binding and evaluation order.

your example will not work because code at the class level is evaluated
when the module is loaded.  but code at the method level is only evaluated
when called, so

class A:
  def __init__(self):
    self.someType = B

class B:
  anotherType = A

will work.

andrew

Not the same. The OP wanted someType to be a class-level attribute,
not an instance level one.

I'm guessing the class mapping is all part of an overall design, so I
would define all of these after creating A and B as empty classes:

class A: pass
class B: pass

A.someType = B
B.anotherType = A

-- Paul
 
R

R. David Murray

Kooks are people too said:
If I try this:

class A:
someType = B

class B:
anotherType = A

I get:
<type 'exceptions.NameError'>: name 'B' is not defined
args = ("name 'B' is not defined",)
message = "name 'B' is not defined"

Presumably because I'm instantiating an instance of a type object (B)
that doesn't exist yet.

You've gotten some answers to how to do this already, but just to be
clear, you aren't instantiating anything in the code above, not even a
type object. someType = B is simply creating 'someType' as a name in the
'class A' namespace that references whatever it is that B references.
This doesn't work, as others have pointed out, because at the point at
which class A's namespace is being constructed, 'B' does not yet have any
value in either the local namespace of class A or the global namespace
of the module.

To figure out how to write code like this that does what you want,
you need to understand how Python namespaces work. A search on
'python namespace' should get you good information. I found this
one, which is a nice summary but doesn't give examples:

http://www.network-theory.co.uk/docs/pytut/PythonScopesandNameSpaces.html
 
M

Miles

I'm guessing the class mapping is all part of an overall design, so I
would define all of these after creating A and B as empty classes:

class A: pass
class B: pass

A.someType = B
B.anotherType = A

While this would work in the general case, it's more iffy with ORM
tools like the App Engine Datastore API. Those classes often have
metaclasses that process the properties when the classes are created,
and tacking on additional properties later is unlikely to work (I
suspect the OP neglected to point out that A and B likely both inherit
from db.Model).

The Django solution is to allow forward references in the form of
strings of class names (e.g., ReferenceType('B')). It doesn't look
like App Engine has a solution for this situation:
http://code.google.com/p/googleappengine/issues/detail?id=811

-Miles
 
K

Kooks are people too

(I
suspect the OP neglected to point out that A and B likely both inherit
from db.Model).
-Miles

yes, I did neglect to state that A and B inherit from db.Model.
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top