Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
242 views
in Technique[技术] by (71.8m points)

function - (Python 3) When to use and when not to use Self in classes, how to pass variables from __init__

I am a brand new to coding (a couple weeks) and im writing some code to webscrape some HTML. The majority of my questions are more structure based about classes and some of the explanations I don't really understand, so if possible try and break it down for me. I am using beautifulsoup to webscrape

I have 2 questions that build on one another:

  1. I am still unsure of when to use self and how to use it, when the point of this class is to really just organize functions, and also that I'd like to practice using classes in general. The confusing part is that it runs without the self argument, but I remember from many other sources I've read that it requires that argument. I suspect it could be a static function but when I try to set that up I don't really understand what I am doing and I get errors. If someone could help me fill in the blanks of my knowledge that would be great.

  2. From what I have read about classes I believe I can use __init__ to define a few variables or processes that all the functions in the class can reference. In this instance I am trying to pass page and soup to the three functions inside class UND as these never change in the program and I hate to repeat the lines of code for every function. The issue is if I try to set up this __init__ to pass the variables, it does not work because I haven't used self. I'm just super confused.

The first box of code is what I am using right now and it works! But I feel I need to address the issues outlined above.

The second box of code is my attempt to use __init__, but it has errors that it is missing 'self'

Thank you to all who may (or may not!) help!

class UND:
    def getFlightCategory():    # Takes the appropriate html text and sets it to a variable
        page = requests.get("http://sof.aero.und.edu")
        soup = BeautifulSoup(page.content, "html.parser")
        flightCategoryClass = soup.find(class_="auto-style1b")
        return flightCategoryClass.get_text()

    def getRestrictions():  # Takes the appropriate html text and sets it to a variable
        page = requests.get("http://sof.aero.und.edu")
        soup = BeautifulSoup(page.content, "html.parser")
        flightRestrictionsClass = soup.find(class_="auto-style4")
        return flightRestrictionsClass.get_text()

    def getInfo():
        return UND.getFlightCategory(), UND.getRestrictions()

class UND:
    def __init__(self):
        page = requests.get("http://sof.aero.und.edu")
        soup = BeautifulSoup(page.content, "html.parser")

    def getFlightCategory(self):    # Takes the appropriate html text and sets it to a variable
        flightCategoryClass = soup.find(class_="auto-style1b")
        return flightCategoryClass.get_text()

    def getRestrictions(self):  # Takes the appropriate html text and sets it to a variable
        flightRestrictionsClass = soup.find(class_="auto-style4")
        return flightRestrictionsClass.get_text()

    def getInfo():
        return UND.getFlightCategory(), UND.getRestrictions()


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your second attempt is close to what you need, but you need to attach the values you want to preserve in __init__ to self as attributes (the instance of the class constructed for you when you make a UND object, which __init__ is responsible for initializing), and you need to read those attributes back out from self later. Here is a fixed version of your code with comments on all additions and modifications and why:

class UND:
    def __init__(self):
        # Doesn't need to be an attribute, since you never use page outside __init__
        page = requests.get("http://sof.aero.und.edu")

        # Needs to be an attribute since you use soup in other methods
        self.soup = BeautifulSoup(page.content, "html.parser")
    #   ^^^^^ New, you need to attach page/soup as attributes of self; otherwise they're regular locals that go away when __init__ returns

    def getFlightCategory(self):    # Takes the appropriate html text and sets it to a variable
        flightCategoryClass = self.soup.find(class_="auto-style1b")
                            # ^^^^^ New, soup is found attached to the self you received
        return flightCategoryClass.get_text()

    def getRestrictions(self):  # Takes the appropriate html text and sets it to a variable
        flightRestrictionsClass = self.soup.find(class_="auto-style4")
                                # ^^^^^ New, is found attached to the self you received
        return flightRestrictionsClass.get_text()

    def getInfo(self):
        #       ^^^^ New, you must receive self as this is an instance method
        return self.getFlightCategory(), self.getRestrictions()
        #      ^^^^                      ^^^^ Changed, call the methods on the self 
        # you received so they receive the existing instance themselves

You'd use this class by creating an instance:

und = UND()

then calling whatever methods you liked on that instance, e.g. print(und.getFlightCategory()) to get the flight category data and print it.

In general, you want to use self for all instance methods in Python. On rare occasion, a method of a class may not rely on an actual instance (it's logically a top-level function, but its usefulness is so tightly bound to the class that it's convenient to have it attached there). In those cases you omit the self argument, and decorate the method with @staticmethod, e.g.:

 class Clock:
     ...  # Rest of class

     @staticmethod
     def bong():
         print("Bong!")

In this case, all clocks go bong the same way; there's no need to refer to an instance to figure out what to do. The method only makes sense in the context of Clock, but it doesn't need a clock, so you make it a static method, which means that you can call Clock.bong() or clock_instance.bong() (e.g. self.bong() in an instance method of Clock) and it will work either way. @classmethod is another exception; I won't go into details here, but it's basically how you make a subclass friendly alternate constructor; you're welcome to research that later, it's not necessary this early in your Python experience.

If you need further information on the purpose of __init__ and self, I strongly recommend reading more on this more general question What __init__ and self do in Python?.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...