Another observation in github: flotilla-python/library/flotilla/__init__.py


#1

In the following two lines of code:

Line 277: def on_connect(self, handler=None):
and
Line 286: def on_disconnect(self, handler=None):

should there be an underscore before the “on”, after “def” ?

i.e.
Line 277: def _on_connect(self, handler=None):
and
Line 286: def _on_disconnect(self, handler=None):

EDIT 5/2/16: I should add that I’m using this module to improve my understanding of Python and I’m not sure if the absence of the underscore has a specific meaning.


#2

The underscore in Python is used to very weakly denote an implementation detail.

It indicates a method that’s used solely inside a class for carrying out some work, but which should never be called by anything using that class. As a basic example:

class DoStuff
    def do_now(self):
        _carry_out_work()
    def _carry_out_work():
        print("Hello!")

In this instance, you’d run:

stuff = DoStuff()
stuff.do_now()

But you would never run:

stuff._carry_out_work()

Because you’d be accessing a function that may be dependent upon something happening in do_now or may even be changed or renamed in future. An implementation detail, rather than a specific part of the class API.

In the case of flotilla, both on_connect and on_disconnect are part of the class API, and provide functions which can be used as decorators. They’re not an implementation detail, and what they do will stay broadly the same throughout versions of Flotilla. However you would generally call them like so:

@flotilla.on_connect():
def my_connect_handler():
    print("Connected!)

Confusingly, the class variables self._on_connect and self._on_disconnect exist too, these are totally discrete from on_connect and on_disconnect and just provide a place to store the connect/disconnect handlers that you might register.

A method like _handle_module_command is an internal command that relies upon some preparation that happens in _handle_command, it’s a structural choice rather than something intended to be part of the public class API.

In future I might break down _handle_module_command into more manageable chunks, break it out into a subclass for parsing commands, or who knows what- the underscore prefix denotes that you should never rely upon or trust that it will stay the same.

So in summary:

_some_method is a private implementation detail subject to change/removal/refactoring across versions

whereas:

some_method is a method that, breaking changes aside, you can always depend upon to be available


#3

Wow, thank you so much for taking the time to provide such a detailed explanation. I’ve tried looking at the Official Python 3 documents but your example looks like something that I’ll be able to get my head around.

Also your most recent change to line 71 in ‘init.py’ no longer throws an error in my script, thanks for that as well. I guess I should subscribe to GitHub in order to track changes in the Python scripts. I’ll edit my previous post to show it’s solved.

Steve

P.S. I’ll try not to use you as a personal tutor in future ;-)


#4

I’m happy to fill that role when I have the time. I owe my career to the people who did it for me! I’m certainly no authority on Python, but I’m at least somewhat proficient!


#5

@rc10b the plan right now is to provide shortly a one-line-installer that you can run periodically (or optionally runs automatically) to keep the flotilla Python API up-to-date (main branch).

Obviously you can already do that with some efforts and know how though, but I think cron can help make it all that much less intensive. Watch this space!