# Another observation in github: flotilla-python/library/flotilla/\_\_init\_\_.py

**URL:** <https://forums.pimoroni.com/t/another-observation-in-github-flotilla-python-library-flotilla---init---py/1745>\
**Category:** Flotilla\
**Created:** [February 4, 2016, 4:59pm UTC](https://forums.pimoroni.com/t/another-observation-in-github-flotilla-python-library-flotilla---init---py/1745 "2016-02-04T16:59:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![rc10b](https://avatars.discourse-cdn.com/v4/letter/r/ba9def/32.png) [@rc10b](https://forums.pimoroni.com/u/rc10b)\
**Post date:** [February 4, 2016, 4:59pm UTC](https://forums.pimoroni.com/t/another-observation-in-github-flotilla-python-library-flotilla---init---py/1745/1 "2016-02-04T16:59:51Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [February 5, 2016, 9:26am UTC](https://forums.pimoroni.com/t/another-observation-in-github-flotilla-python-library-flotilla---init---py/1745/2 "2016-02-05T09:26:47Z")

</div>

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:

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

```

In this instance, you’d run:

```python
stuff = DoStuff()
stuff.do_now()

```

But you would never run:

```python
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:

```python
@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

---

<div class="post-metadata">

**Author:** ![rc10b](https://avatars.discourse-cdn.com/v4/letter/r/ba9def/32.png) [@rc10b](https://forums.pimoroni.com/u/rc10b)\
**Post date:** [February 5, 2016, 9:59am UTC](https://forums.pimoroni.com/t/another-observation-in-github-flotilla-python-library-flotilla---init---py/1745/3 "2016-02-05T09:59:31Z")

</div>

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 ;-)

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [February 5, 2016, 10:16am UTC](https://forums.pimoroni.com/t/another-observation-in-github-flotilla-python-library-flotilla---init---py/1745/4 "2016-02-05T10:16:49Z")

</div>

> [@rc10b](#):
>
> P.S. I’ll try not to use you as a personal tutor in future ;-)

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!

---

<div class="post-metadata">

**Author:** ![RogueM](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/roguem/32/311_2.png) [@RogueM](https://forums.pimoroni.com/u/RogueM)\
**Post date:** [February 5, 2016, 11:00am UTC](https://forums.pimoroni.com/t/another-observation-in-github-flotilla-python-library-flotilla---init---py/1745/5 "2016-02-05T11:00:11Z")

</div>

@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!
