Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python classes that refer to each other

Tags:

python

oop

django

I have two classes that refer to each other, but obviously the compiler complains. Is there any way around this?

EDIT

Actually my code is slightly different than what Hank Gay uses. So python can definitely deal with some kinds of circular references, but it tosses an error in the following situation. Below is what I've got and I get an 'name Y not defined error'

class X(models.Model):

        creator = Registry()
        creator.register(Y)

class Y(models.Model):
    a = models.ForeignKey(X)
    b = models.CharField(max_length=200)

Hope this helps clarify. Any suggestions.

like image 561
Daniel Avatar asked Jun 25 '09 20:06

Daniel


People also ask

How do you call two classes in Python?

I instance the class A in class B. init. And I pass B itself to A's function using the instance which I just defined. Next I call B's function AFunctionFromA through function ExecAFunction in A.So now I can call functions between two classes.

How do you link one class to another in Python?

If we have two different classes and one of these defined another class on calling the constructor. Then, the method and attributes of another class can be accessed by first class objects ( i.e; objects within objects ). Here in the below example we learn to access object (its methods and attributes) within an object.

Can two classes inherit from each other Python?

A class can be derived from more than one base class in Python, similar to C++. This is called multiple inheritance. In multiple inheritance, the features of all the base classes are inherited into the derived class. The syntax for multiple inheritance is similar to single inheritance.

Can you have multiple classes in Python?

As all of us know, Python supports multiple inheritance, what means, in Python, a class can inherit features and attributes from multiple classes. MRO or Method Resolution Order is the hierarchy in which base classes are searched when looking for a method in the parent class. There are two types of classes in python.


2 Answers

In python, the code in a class is run when the class is loaded.

Now, what the hell does that mean? ;-)

Consider the following code:

class x:
    print "hello"
    def __init__(self): print "hello again"

When you load the module that contains the code, python will print hello. Whenever you create an x, python will print hello again.

You can think of def __init__(self): ... as equivalent with __init__ = lambda self: ..., except none of the python lambda restrictions apply. That is, def is an assignment, which might explain why code outside methods but not inside methods is run.

When your code says

class X(models.Model):
    creator = Registry()
    creator.register(Y)

You refer to Y when the module is loaded, before Y has a value. You can think of class X as an assignment (but I can't remember the syntax for creating anonymous classes off-hand; maybe it's an invocation of type?)

What you may want to do is this:

class X(models.Model):
    pass
class Y(models.Model):
    foo = something_that_uses_(X)
X.bar = something_which_uses(Y)

That is, create the class attributes of X which reference Y after Y is created. Or vice versa: create Y first, then X, then the attributes of Y which depend on X, if that's easier.

Hope this helps :)

like image 172
Jonas Kölker Avatar answered Oct 05 '22 03:10

Jonas Kölker


The error is that execution of creator.register(Y) is attempted during the (executable) definition of class X, and at that stage, class Y is not defined. Understand this: class and def are statements that are executed (typically at import time); they are not "declarations".

Suggestion: tell us what you are trying to achieve -- perhaps as a new question.

like image 35
John Machin Avatar answered Oct 05 '22 04:10

John Machin