I often see this pattern:
class Foo:
def __init__(self, bar):
self._bar = bar
def bar(self):
return _bar
Why would that be preferable to this?
class Foo:
def __init__(self, bar)
self.bar = bar
I often see this pattern:
class Foo:
def __init__(self, bar):
self._bar = bar
def bar(self):
return _bar
Why would that be preferable to this?
class Foo:
def __init__(self, bar)
self.bar = bar
It de-couples the external representation of bar
from its internal representation.
In your first code, this would be preferable sometimes for some reasons. For one, in Python _name
is just a naming convention that indicates to the developer that _name
should not be accessed from outside the place where its define, be it a class, a module or whatever. This naming convention also helps to avoid name collisions, especially if the attribute is critical in terms of functionality.
Let's demonstrate with real examples. You'll find many examples of these in the os.py
module, for instance:
# Helper for popen() -- a proxy for a file whose close waits for the process
class _wrap_close:
def __init__(self, stream, proc):
self._stream = stream
self._proc = proc
...
_wrap_close
is a wrapper class that's returned when you call os.popen
._proc
. This doesn't just indicate that you shouldn't access this directly in your code, but also might be an indicator that this attribute is critical to the functionality of the class, if you look inside, os.popen
you will probably see why:
# Supply os.popen()
def popen(cmd, mode="r", buffering=-1):
# many code omitted here...
if mode == "r":
proc = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
bufsize=buffering)
return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
# many code omitted here... (see os.py)
_wrap_close
is a wrapper class around the object returned by Popen
and in fact _wrap_close
delegates many operations and accesses to self._proc
. _wrap_close
itself uses _name
naming convention.
In some cases:
def bar(self):
return self._bar
typically there would be some processing and logic prior to returning self._bar
. Also properties and descriptors can be used as well. Different developers use different features for different reasons.