简体   繁体   中英

Python class defined in the same file as another class - how do you get access to the one defined later in the file?

I'm very new to Python, I figure this question should be easy to answer.

My problem simplified is this...

I have 2 classes in a File class A and class B. Class A is defined first in the file and class B is defined second.

class A
    ...

class B
    ...

How do I get access to class B with class A?

class A
    something = B

class B
    somethingElse = A

Here is the actual code I'm trying to fix

class FirstResource(_ModelResource):
    class Meta(_Meta):
        queryset = First.objects.all()
        resource_name = 'first'
        allowed_methods = ['get','put']

        filtering = {
            'a': ALL_WITH_RELATIONS,
            'b': ALL_WITH_RELATIONS,
            'c': ALL_WITH_RELATIONS,
        }

        ordering = ['apt']

    # this is the line that would fix everything
    second = fields.ForeignKey(SecondResource, 'second', null=True, blank=True, default=None, full=True) 

    ...

 class SecondResource(_ModelResource):
    class Meta(_Meta):
        queryset = Second.objects.all()
        resource_name = 'second'
        execute_methods = ['get', 'post']
        filtering = {
            'name': ['exact'],
            'leader': ['exact'],
        }   

    super = fields.ForeignKey(FirstResource, 'super', null=True, blank=True, default=None, full=True)
    leader = fields.ForeignKey(FirstResource, 'leader', null=True, blank=True, default=None, full=True)

    ...

With no pre-declaring in Python I'm really not sure how to solve this problem. The First in models.py has a ForeignKey of Second, and Second has 2 Foreign keys of First.

Moving A below B does not solve the problem since B also needs A. I didn't write the code I'm simply trying to fix it - I need the 'second' foreign key back when I do a 'get' for the resource in both classes.

So the answer was to use qoutes

B = fields.ForeignKey('api.resources.B', 'B')

To access B , you must first have defined B .

If you want to access B when you define A , you need to move it above A in the file.

If you want to access B when you call methods in A , you don't need to do anything: by the time you call a method of A , the interpreter has executed all the definitions.

When python finds a class declaration it creates a new scope and executes the code inside the class in this code block. This means that all class variables are instantiated when the class declaration is executed.

Now, if you have the two classes like:

class A:
    something = B

class B:
   pass

Python will execute something = B before creating the B class and thus it yields a NameError .

You can avoid this in a really simple manner:

class A:
    something = None

class B:
    pass

A.something = B
class A:
    def __init__(self):
        print "In A"

class B:
    def __init__(self):
        a = A()
        print "In B"
b = B()

I think you want something like that.

A workaround that comes to my mind is to separate the classes into multiple files, so you could have a python package "models" in which you'll have A.py and B.py. Then you avoid the ordering issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM