I would like to know which would be more pythonic way to write python code using _ in modules, classes and methods.
Example 1:
import threading as _threading
class Thread(_threading.Thread):
pass
vs
from threading import Thread
class MyThread(Thread):
pass
on module level does it make sense to introduce private vars in methods like this:
def my_module_method():
_throw = foo + bar
return _throw
vs
def my_module_method():
throw = foo + bar
return throw
Am I correct to assume that best usage of private name would be to prevent instance of the class to use some private temp method eg:
class MyClass(object):
_my_internal = 0
def _do_not_use_me()
pass
so that enduser of that class would know not to use those methods directly in:
foo = MyClass._do_not_use_me()
bar = MyClass._my_internal
Any other advice on general usage of private names would be highly appreciated.
Keep in mind, with Python nothing is "hard rules" more conventions. With some exceptions, there's nothing wrong with prefixing your variables with whatever you want, as long as you are consistent and your code is easy to understand.
However, if you want to follow the common convention, do read on.
As Python doesn't have access modifiers like some other languages (access modifiers like private
, public
, protected
, etc), the _
prefix marks fields, methods, etc in classes that are not to be accessed externally. It marks private use.
With that in mind, let's look at your examples one by one:
The prefered way is:
from threading import Thread
class MyThread(Thread):
pass
You may also use:
import threading
class MyThread(threading.Thread):
pass
But you should not _
prefix imported modules.
Under ordinary circumstances, you do not have access to the inner variables of functions. As a result there is no reason to use _
. Thus this is the way:
def my_module_method():
throw = foo + bar
return throw
The only exception I can think of, is in the case of nested functions, where you may replicate names and to avoid ambiguity you would use _
to differentiate between variables:
def my_outer_method():
throw = foo + bar
def my_inner_method(_throw):
return _throw * 2
return my_inner_method(throw)
Yes, this is the exact reason why you would use the _
prefix.
my_class = MyClass()
foo = my_class._do_not_use_me()
bar = my_class._my_internal
This tells the consumer of the class that they are doing something they are not supposed to or something that isn't safe.