-2

I have this code:

class CongressApi:
    class apiKeyError(Exception):
        pass

    class Member:
        def __init__(self):
            print("self.makeRequest()?") # want to call the makeRequest function in the external class

    def __init__(self, apiKey):
        self.key = apiKey

    def makeRequest(self, req):
        ret = requests.get(f"https://api.propublica.org/congress/v1/{req}", headers={"X-API-Key": self.key})
        return ret.content

I would like to be able to call that makeRequest() function from inside the memeber class. is this possible?

Avi Baruch
  • 112
  • 2
  • 8
  • 8
    You need an instance, the same as always. Why are you nesting the class to begin with? – juanpa.arrivillaga Feb 11 '21 at 14:52
  • 5
    There is no particular relation between `Member` and `CongressAPI`; an instance of `Member` does not have access to `CongressAPI` methods. Why is the class nested in the first place? This is *not* a common idiom in Python like it is in, say, Java, since you can easily define multiple classes in a single module. – chepner Feb 11 '21 at 14:53
  • Can you please clarify what you expect the code to do? ``makeRequest`` is a method of ``CongressApi``; ``Member`` is not a ``CongressApi``, and needs an instance of the latter to call its methods properly. *Which* ``CongressAPI`` instance should a new ``Member`` use to call ``makeRequest``? – MisterMiyagi Feb 11 '21 at 14:57
  • https://stackoverflow.com/questions/2024566/how-to-access-outer-class-from-an-inner-class – basckerwil Feb 11 '21 at 14:58

2 Answers2

1

It is not common practice in Python to nest classes like this. I would recommend something like this instead:

class CongressApi:
    def __init__(self, apiKey):
        self.key = apiKey

    def makeRequest(self, req):
        ret = requests.get(f"https://api.propublica.org/congress/v1/{req}", headers={"X-API-Key": self.key})
        return ret.content

class Member:
        def __init__(self, congress_api_key):
            self.C = CongressAPI(congress_api_key)
            print(f"{self.C.makeRequest()}")

class apiKeyError(Exception):
        pass # this is really unnecessary - it's easier just to implement try/except blocks at each point in the code where an exception might be triggered.

In general, it's good practice to separate out your classes.

v0rtex20k
  • 1,041
  • 10
  • 20
0

If you want your internal class's instance methods to be able to access instance methods of the outer class, the internal class's instance needs access to an instance of the external class. For example:

class CongressApi:

    class Member:
        def __init__(self, api):
            api.makeRequest("bar")

    def __init__(self, apiKey):
        self.key = apiKey

    def makeRequest(self, req):
        print(f"making request {req} with apiKey {self.key}")

    def do_member_thing(self):
        member = self.Member(self)


api = CongressApi("foo")
api.do_member_thing()  # making request bar with apiKey foo

Note that this is not actually a sensible way to organize your classes -- typically the point of an inner class would be to encapsulate some piece of state that doesn't depend on the outer class, and further to abstract that implementation away from the rest of the outer class's implementation. Passing the inner class a reference to the outer class is permitted, but it also entirely defeats the purpose from an architectural standpoint.

Samwise
  • 68,105
  • 3
  • 30
  • 44