FAQ
For example: I'm writing simple class:

class Numbers:
def __init__(self, numbers):
self._numbers = numbers
def get_all(self):
for number in self._numbers:
yield number

If I want to add another method for yielding even numbers only, I may
use:

def get_even(self):
for numbers in self._numbers:
if numbers % 2 == 0:
yield number

or, I can use public method 'get_all' instead of using private
attribute '_numbers', like:

def get_even(self):
for numbers in self.get_all():
if numbers % 2 == 0:
yield number

Which coding style do you prefer? I'm more toward public API way,
since it requires less code change if I refactor private data
structure later.
Plz give pros and cons of these.

Search Discussions

  • Inyeol at Jan 5, 2011 at 4:52 am
    I found typo after posting: local name 'numbers' and 'number' are
    mixed.
    Plz don't report bug but focus on coding style only :-)
  • Josh English at Jan 5, 2011 at 5:31 am
    I think it depends on where you're willing to deal with changes. As it stands, if you make changes to get_all that will effect the way get_even works. If there's a logical chain that your code needs to follow and such changes would be acceptable, use them, because it's easier to change one thing once instead of one thing twice.


    In general, I try to code in a way that will reduce the number of places I'll have to change or refactor.

    Josh
  • Carl Banks at Jan 5, 2011 at 11:37 am

    On Jan 4, 8:46?pm, Inyeol wrote:
    For example: I'm writing simple class:

    ? ? class Numbers:
    ? ? ? ? def __init__(self, numbers):
    ? ? ? ? ? ? self._numbers = numbers
    ? ? ? ? def get_all(self):
    ? ? ? ? ? ? for number in self._numbers:
    ? ? ? ? ? ? ? ? yield number

    If I want to add another method for yielding even numbers only, I may
    use:

    ? ? ? ? def get_even(self):
    ? ? ? ? ? ? for numbers in self._numbers:
    ? ? ? ? ? ? ? ? if numbers % 2 == 0:
    ? ? ? ? ? ? ? ? ? ? yield number

    or, I can use public method 'get_all' instead of using private
    attribute '_numbers', like:

    ? ? ? ? def get_even(self):
    ? ? ? ? ? ? for numbers in self.get_all():
    ? ? ? ? ? ? ? ? if numbers % 2 == 0:
    ? ? ? ? ? ? ? ? ? ? yield number

    Which coding style do you prefer? I'm more toward public API way,
    since it requires less code change if I refactor private data
    structure later.
    Plz give pros and cons of these.
    Using Public API makes it easier to subclass, if you want to redefine
    the meaning of "all" somehow. The main reason to avoid Public API is
    to get performance benefits (most Python built-in classes access the
    internal structure directly for this reason). There are occasions
    where a function really needs to access the internals and not the
    "visible" value.

    Also, in Python it's reasonable to consider an instance variable to be
    part of the public interface of a class, because backwards-
    incompatible changes can be avoided using properties.


    Carl Banks
  • Jean-Michel Pichavant at Jan 5, 2011 at 3:18 pm

    Inyeol wrote:
    For example: I'm writing simple class:

    class Numbers:
    def __init__(self, numbers):
    self._numbers = numbers
    def get_all(self):
    for number in self._numbers:
    yield number

    If I want to add another method for yielding even numbers only, I may
    use:

    def get_even(self):
    for numbers in self._numbers:
    if numbers % 2 == 0:
    yield number

    or, I can use public method 'get_all' instead of using private
    attribute '_numbers', like:

    def get_even(self):
    for numbers in self.get_all():
    if numbers % 2 == 0:
    yield number

    Which coding style do you prefer? I'm more toward public API way,
    since it requires less code change if I refactor private data
    structure later.
    Plz give pros and cons of these.
    - Unless you already know that you'll need to refactor the structure
    later, there's no need to anticipate => unnecessary optimization

    - Using public API deos not necessarily make refactoring easier.
    Let me explain, public APIs are meant to be called by external objects.
    These APIs may need to do some things that internal computing doesn't.
    For instance, let's say you add a logging statement in the get_all()
    method. Every call triggers a log entry. Does the get_even method want
    to log this call ? Maybe not. In that particular case, using the
    internal strucutre is preferable.

    - If you agree to the statement that readability > edition, then you
    should care more about writing clean and concise code, than refactorable
    ( :D ) code. Using self._numbers raises less questions to the reader.
    Though I admit that question raised by get_all are answered in 5 seconds
    (the question being 'If he used an method instead of _numbers, this
    method must do something special')

    - In fine, it doesn't really matter in the example you gave above.

    JM
  • Neil Cerutti at Jan 5, 2011 at 4:26 pm

    On 2011-01-05, Inyeol wrote:
    For example: I'm writing simple class:

    class Numbers:
    def __init__(self, numbers):
    self._numbers = numbers
    def get_all(self):
    for number in self._numbers:
    yield number

    If I want to add another method for yielding even numbers only,
    I may use:

    def get_even(self):
    for numbers in self._numbers:
    if numbers % 2 == 0:
    yield number

    or, I can use public method 'get_all' instead of using private
    attribute '_numbers', like:

    def get_even(self):
    for numbers in self.get_all():
    if numbers % 2 == 0:
    yield number

    Which coding style do you prefer? I'm more toward public API
    way, since it requires less code change if I refactor private
    data structure later. Plz give pros and cons of these.
    Decoupling a member function from its own internal state would be
    of little benefit.

    However, decoupling an interface from its implementation can be a
    good idea. Python provides inheritance and the NotImplmented
    exception to help with that. Duck-typing is another popular
    approach.

    --
    Neil Cerutti
  • Jacek Krysztofik at Jan 5, 2011 at 4:59 pm
    Sorry for OT, but this is actually a question of mine
    if numbers % 2 == 0:
    wouldn't the following be faster?
    if numbers & 1 == 0:
    JK
  • Peter Otten at Jan 5, 2011 at 5:15 pm

    Jacek Krysztofik wrote:

    Sorry for OT, but this is actually a question of mine
    if numbers % 2 == 0:
    wouldn't the following be faster?
    if numbers & 1 == 0:
    You can answer that and similar questions yourself with the timeit module:

    $ python -m timeit -s'm, n = 1234, 1235' 'm % 2 == 0; n % 2 == 0'
    1000000 loops, best of 3: 0.377 usec per loop

    $ python -m timeit -s'm, n = 1234, 1235' 'm & 1 == 0; n & 1 == 0'
    1000000 loops, best of 3: 0.298 usec per loop

    So yes, a binary and seems to be faster.
  • Carey Tilden at Jan 6, 2011 at 9:19 pm

    On Wed, Jan 5, 2011 at 9:15 AM, Peter Otten wrote:

    Jacek Krysztofik wrote:
    Sorry for OT, but this is actually a question of mine
    if numbers % 2 == 0:
    wouldn't the following be faster?
    if numbers & 1 == 0:
    You can answer that and similar questions yourself with the timeit module:

    $ python -m timeit -s'm, n = 1234, 1235' 'm % 2 == 0; n % 2 == 0'
    1000000 loops, best of 3: 0.377 usec per loop

    $ python -m timeit -s'm, n = 1234, 1235' 'm & 1 == 0; n & 1 == 0'
    1000000 loops, best of 3: 0.298 usec per loop

    So yes, a binary and seems to be faster.
    I would be curious to hear of a Python application where such a small speed
    difference mattered even a little bit. Looks to me like a pretty
    meaningless difference.

    Carey
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: <http://mail.python.org/pipermail/python-list/attachments/20110106/3a069875/attachment-0001.html>
  • Paul Rubin at Jan 5, 2011 at 5:44 pm

    Inyeol <inyeol.lee at gmail.com> writes:
    def get_all(self):
    for number in self._numbers:
    yield number
    I think

    def get_all(self):
    return iter(self._numbers)

    is more direct.
  • DevPlayer at Jan 13, 2011 at 1:15 am

    On Jan 4, 11:46?pm, Inyeol wrote:
    Which coding style do you prefer? I'm more toward public API way,
    since it requires less code change if I refactor private data
    structure later.
    Plz give pros and cons of these.
    Great question. It gets at the heart of Python style.
    It's a tricky question and can be answered so many ways. I'm not a pro-
    programmer anymore so here's my hobbyst's take on it.

    First, API is application programming interface. Follow me for a sec.
    It's the interface that your programmers use to use your "package".
    But WHICH programmers? For large apps like game developers or large
    all encompassing apps for companys there are many different types of
    programmers. That helps determine how heavy to lean towards private
    verse public interfaces.

    Funny thing is I end up using the private interfaces as much as the
    public interaces for certain things. For example when coding in
    wxPython I rarely use any private apis (ie. __dict__ or other "special
    or magic named" attributes). But when coding outside of wxPython I'm
    all over the place defining new classes with special named attributes
    like __new__ or __metaclass__, and lots and lots of other magic named
    methods and private attributes.

    So one way to decide whether to be coding towards more public verse
    private is where in your project you are. Building infrastructure and
    framework verse building "application" and end-user interfaces.

    Or similarly the interface TO the API interface is private (as far as
    Python considers things private that is). The interface to all others
    to use your "package" is public.

    And if your code is not a package for other coders, then what is the
    sense in having private anythings?

    One thing that mungles one's mind into thinking it matters is your IDE
    tools. When you run your scripts as an end user, who cares that
    there's tons of objects cluttering your namespace - I'm implying that
    using private API in that case is somewhat a waste. When in your IDE
    coding like PyCrust and you type in the interface something like wx.
    you'll get a popup of "attributes" and you think "ah, these attributes
    and methods I can use". But in use of that program, there's no sense
    in hidding stuff with underscored names.

    On the otherhand. I like to think my namespaces are simple, clean,
    uncluttered. There's less "What the heck is that thing" while looking
    at dir() and debugging.

    Personally I do not like the underscore. My hands don't like the
    keystroke pattern. And the underscore is butt ugly to me. Ugly does
    not equal "less readable". I find underscore easier to read then camel
    case/Hungarian Notation (wx and .NET has a lot of that). Although name
    mangling and camel case usage are different things, from a visual (of
    source code), to me they are the same. Also when there is name
    mangling, there is often an unmangled version of it in some usage
    somewhere in your code.

    Another thought. Although private interfaces are not intended to be
    SEEN, you code your private interfaces (i.e. attributes and methods,
    functions, etc) to denote themselves as private when you LOOK at them
    by using underscores. I'd rather have my source code just color
    private attributes differently. However editors are not at that level
    yet (meaning they'd have to interpret the code to know what's
    private).

    Lastly. Shouldn't it be better to use APIs based on the docs instead
    of analyzing the code for intended public interfaces verse private
    ones?

    Although not explicidly listing pros and cons to public verse private
    APIs I hope I spark some useful insight.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedJan 5, '11 at 4:46a
activeJan 13, '11 at 1:15a
posts11
users10
websitepython.org

People

Translate

site design / logo © 2022 Grokbase