简体   繁体   中英

Where to define a method that is used only inside __init__ and must not be called anywhere else?

class Line(object):
    def __init__(self):
        self.length = None
        self.run_equation()

    def run_equation(self):
        # it runs through a formula then assigns the end value to length
        self.length = 50 # 50 for example

Now I want to populate a list with few Line objects. The thing is I dont want run_equation() to be called ever again becouse I allready assigned the attribute inside __init__ , and it's value must not be changed.

What approaches should I follow, or do I have to stick this mind and simply not calling the method from the instance?

PS: Didn't find much on google or I just don't know how to search for this question.

Python tries to hide methods and data that start with 2 underbars from outside users. Its not perfect, but the underbars tell programmers that you really don't want them to fiddle with them. Add a property to get a read only view of length, and I think you'll have what you want:

class Line(object):
    @property
    def length(self):
        """The length of the line"""
        return self.__length

    def __init__(self):
        """Create a line"""
        self.__length = None
        self.__run_equation()

    def _run_equation(self):
        self.__length = 50

A trial run shows limited access

>>> from line import Line
>>> l=Line()
>>> l.length
50
>>> l.length = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> l.__length = 1
>>> l.__run_equation()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Line' object has no attribute '__run_equation'
>>> l.length
50

>>> help(Line)
Help on class Line in module line:

class Line(__builtin__.object)
 |  Methods defined here:
 |  
 |  __init__(self)
 |      Create a line
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  length
 |      The length of the line

If there's only a single place where this is used—in __init__ —then you don't need a separate method to begin with. Just put the contents of that method into your __init__ directly:

class Line (object):
    def __init__ (self):
        self.length = 50

It's possible to define a function inside another function, and it will only be visible from the containing function:

def example():
    def pointless_function():
        print("Why do I exist, again?")
    pointless_function()

example()
pointless_function()

You could get rid of it once you're done:

class Line(object):
    def __init__(self):
        self.length = None
        self.assign_value_to_length()
        self.assign_value_to_length = None

    def assign_value_to_length(self):
        self.length = 50

This isn't very good practice, though. Instead, I'd just add an assertion:

    def assign_value_to_length(self):
        assert self.length is None
        self.length = 50

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