While reviewing some code used in the online CS188.1x class on edX.org (code written by the instructors), I noticed the repeated use of a single set of double quotes (like one might use around a str) for use as comments.
I haven't seen this before, nor is it mentioned in PEP8 that I could find, but it certainly seems to work fine. Can anyone enlighten me?
Here's an example:
class SomeClass():
"""
Some docstring info, using standard 'triple double quotes'
"""
def __init__(self):
"This is the comment style to which I'm referring."
some.code = foo # Here's a normal inline comment
def bar(self, item):
"Here is another example of the comment style"
return wtf
A docstring is any string literal that appears as the first statement in a class, method, function or module. Stylistically it's typical and preferred to use the triple quote format to allow for longer, better formatted docstrings, and to call attention to them for easy reference, but any string will qualify.
Docstrings are distinct from comments because comments are not relevant to the execution of a program at all, whereas docstrings are available at runtime by accessing an object's __doc__ variable.
That's just docstring. It's a good design recommendation. For example, if you load that class in your python shell, you can call a help(bar) and you'll get "Here is another example of the comment style"
Related
I have a class with several similar methods, each with long docstrings that are similar but vary with regards to several phrases/words. I'd like to build a docstring template and then apply string formatting to it. Below is a clumsy implementation where the __doc__s are defined after the class methods.
capture_doc = """
%(direc)s normal.
a %(sym)s b."""
class Cls():
def a(self):
pass
def b(self):
pass
a.__doc__ = capture_doc % {'direc' : 'below', 'sym' : '<'}
b.__doc__ = capture_doc % {'direc' : 'above', 'sym' : '>'}
c = Cls()
print(c.a.__doc__)
below normal.
a < b.
Question: is there a Python docs- or PEP-prescribed way to do this? I'd like to keep things basic, I've seen use of an #Appender decorator but think that's a bit fancy for my needs.
You shouldn't do this. You seem to assume your docstring should only serve those who use your code and need help with how it works.
Docstrings are supposed to provide some form of the documentation for the associated object for those reading your code, so this makes your docstring half its worth. I doubt any one would love to go through the trouble of having to format those strings (in their heads or using the interpreter) to figure out what your code does or how it works.
From PEP 257:
What is a Docstring?
A docstring is a string literal that occurs as the first statement
in a module, function, class, or method definition. Such a docstring
becomes the __doc__ special attribute of that object.
[Emphasis mine]
With your implementation, one could pedantically argue you don't have docstrings albeit __doc__ attributes.
Can you explain the concept stubbing out functions or classes taken from this article?
class Loaf:
pass
This class doesn't define any methods or attributes, but syntactically, there needs to be something in the definition, so you use pass. This is a Python reserved word that just means “move along, nothing to see here”. It's a statement that does nothing, and it's a good placeholder when you're stubbing out functions or classes.`
thank you
stubbing out functions or classes
This refers to writing classes or functions but not yet implementing them. For example, maybe I create a class:
class Foo(object):
def bar(self):
pass
def tank(self):
pass
I've stubbed out the functions because I haven't yet implemented them. However, I don't think this is a great plan. Instead, you should do:
class Foo(object):
def bar(self):
raise NotImplementedError
def tank(self):
raise NotImplementedError
That way if you accidentally call the method before it is implemented, you'll get an error then nothing happening.
A 'stub' is a placeholder class or function that doesn't do anything yet, but needs to be there so that the class or function in question is defined. The idea is that you can already use certain aspects of it (such as put it in a collection or pass it as a callback), even though you haven't written the implementation yet.
Stubbing is a useful technique in a number of scenarios, including:
Team development: Often, the lead programmer will provide class skeletons filled with method stubs and a comment describing what the method should do, leaving the actual implementation to other team members.
Iterative development: Stubbing allows for starting out with partial implementations; the code won't be complete yet, but it still compiles. Details are filled in over the course of later iterations.
Demonstrational purposes: If the content of a method or class isn't interesting for the purpose of the demonstration, it is often left out, leaving only stubs.
Note that you can stub functions like this:
def get_name(self) -> str : ...
def get_age(self) -> int : ...
(yes, this is valid python code !)
It can be useful to stub functions that are added dynamically to an object by a third party library and you want have typing hints.
Happens to me... once :-)
Ellipsis ... is preferable to pass for stubbing.
pass means "do nothing", whereas ... means "something should go here" - it's a placeholder for future code. The effect is the same but the meaning is different.
Stubbing is a technique in software development. After you have planned a module or class, for example by drawing it's UML diagram, you begin implementing it.
As you may have to implement a lot of methods and classes, you begin with stubs. This simply means that you only write the definition of a function down and leave the actual code for later. The advantage is that you won't forget methods and you can continue to think about your design while seeing it in code.
The reason for pass is that Python is indentation dependent and expects one or more indented statement after a colon (such as after class or function).
When you have no statements (as in the case of a stubbed out function or class), there still needs to be at least one indented statement, so you can use the special pass statement as a placeholder. You could just as easily put something with no effect like:
class Loaf:
True
and that is also fine (but less clear than using pass in my opinion).
Is there a generally accepted way to comment functions in Python? Is the following acceptable?
#########################################################
# Create a new user
#########################################################
def add(self):
The correct way to do it is to provide a docstring. That way, help(add) will also spit out your comment.
def add(self):
"""Create a new user.
Line 2 of comment...
And so on...
"""
That's three double quotes to open the comment and another three double quotes to end it. You can also use any valid Python string. It doesn't need to be multiline and double quotes can be replaced by single quotes.
See: PEP 257
Use docstrings.
This is the built-in suggested convention in PyCharm for describing function using docstring comments:
def test_function(p1, p2, p3):
"""
test_function does blah blah blah.
:param p1: describe about parameter p1
:param p2: describe about parameter p2
:param p3: describe about parameter p3
:return: describe what it returns
"""
pass
Use a docstring, as others have already written.
You can even go one step further and add a doctest to your docstring, making automated testing of your functions a snap.
Use a docstring:
A string literal that occurs as the first statement in a module, function, class, or method definition. Such a docstring becomes the __doc__ special attribute of that object.
All modules should normally have docstrings, and all functions and classes exported by a module should also have docstrings. Public methods (including the __init__ constructor) should also have docstrings. A package may be documented in the module docstring of the __init__.py file in the package directory.
String literals occurring elsewhere in Python code may also act as documentation. They are not recognized by the Python bytecode compiler and are not accessible as runtime object attributes (i.e. not assigned to __doc__ ), but two types of extra docstrings may be extracted by software tools:
String literals occurring immediately after a simple assignment at the top level of a module, class, or __init__ method are called "attribute docstrings".
String literals occurring immediately after another docstring are called "additional docstrings".
Please see PEP 258 , "Docutils Design Specification" [2] , for a detailed description of attribute and additional docstrings...
The principles of good commenting are fairly subjective, but here are some guidelines:
Function comments should describe the intent of a function, not the implementation
Outline any assumptions that your function makes with regards to system state. If it uses any global variables (tsk, tsk), list those.
Watch out for excessive ASCII art. Having long strings of hashes may seem to make the comments easier to read, but they can be annoying to deal with when comments change
Take advantage of language features that provide 'auto documentation', i.e., docstrings in Python, POD in Perl, and Javadoc in Java
I would go for a documentation practice that integrates with a documentation tool such as Sphinx.
The first step is to use a docstring:
def add(self):
""" Method which adds stuff
"""
Read about using docstrings in your Python code.
As per the Python docstring conventions:
The docstring for a function or method should summarize its behavior and document its arguments, return value(s), side effects, exceptions raised, and restrictions on when it can be called (all if applicable). Optional arguments should be indicated. It should be documented whether keyword arguments are part of the interface.
There will be no golden rule, but rather provide comments that mean something to the other developers on your team (if you have one) or even to yourself when you come back to it six months down the road.
I would go a step further than just saying "use a docstring". Pick a documentation generation tool, such as pydoc or epydoc (I use epydoc in pyparsing), and use the markup syntax recognized by that tool. Run that tool often while you are doing your development, to identify holes in your documentation. In fact, you might even benefit from writing the docstrings for the members of a class before implementing the class.
While I agree that this should not be a comment, but a docstring as most (all?) answers suggest, I want to add numpydoc (a docstring style guide).
If you do it like this, you can (1) automatically generate documentation and (2) people recognize this and have an easier time to read your code.
You can use three quotes to do it.
You can use single quotes:
def myfunction(para1,para2):
'''
The stuff inside the function
'''
Or double quotes:
def myfunction(para1,para2):
"""
The stuff inside the function
"""
The correct way is as follows:
def search_phone_state(phone_number_start,state,dataframe_path,separator):
"""
returns records whose phone numbers begin with a phone_number_start and are from state
"""
dataframe = pd.read_csv(filepath_or_buffer=dataframe_path, sep=separator, header=0)
return dataframe[(pd.Series(dataframe["Phone"].values.tolist()).str.startswith(phone_number_start, na="False"))& (dataframe["State"]==state)]
If you do:
help(search_phone_state)
It will print:
Help on function search_phone_state in module __main__:
search_phone_state(phone_number_start, state, dataframe_path, separator)
returns records whose phone numbers begin with a phone_number_start and are from state
I was trying to create a python wrapper for an tk extension, so I looked at Tkinter.py to learn how to do it.
While looking at that file, I found the following pattern appears a lot of times: an internal method (hinted by the leading "_" in the method name) is defined, then a public method is defined just to be the internal method.
I want to know what's the benefit of doing this.
For example, in the code for class Misc:
def _register(self, func, subst=None, needcleanup=1):
# doc string and implementations is removed since it's not relevant
register = _register
Thank you.
Sometimes, you may want to change a method's behavior. For example, I could do this (hypothetically within the Misc class):
def _another_register(self, func, subst=None, needcleanup=1):
...
def change_register(self):
self.register = self._another_register
def restore_register(self):
self.register = self._register
This can be a pretty handy way to alter the behavior of certain pieces of code without subclassing (but it's generally not advisable to do this kind of thing except within the class itself).
From PEP8
In addition, the following special forms using leading or trailing
underscores are recognized (these can generally be combined with any case
convention):
_single_leading_underscore: weak
"internal use" indicator. E.g. "from
M import *" does not import objects
whose name starts with an underscore.
Well, I'm supposing, there could be another internal callable, that could've been used, it just didn't make it to the version you have. Generally, I think it is a good idea - you expose one symbol publically and internally it can be anything, a real method, a stubbed out method, a debug version of the method, anything.
Regarding the "standard" way to put comments inside Python source code:
def func():
"Func doc"
... <code>
'TODO: fix this'
#badFunc()
... <more code>
def func():
"Func doc"
... <code>
#TODO: fix this
#badFunc()
... <more code>
I prefer to write general comments as strings instead of prefixing #'s.
The official Python style guide doesn't mention using strings as comments (If I didn't miss it while reading it).
I like it that way mainly because I think the # character looks ugly with comment blocks. As far as I know these strings don't do anything.
Are there disadvantages in doing this?
Don't misuse strings (no-op statements) as comments. Docstrings, e.g. the first string in a module, class or function, are special and definitely recommended.
Note that docstrings are documentation, and documentation and comments are two different things!
Documentation is important to understand what the code does.
Comments explain how the code does it.
Documentation is read by people who use your code, comments by people who want to understand your code, e.g. to maintain it.
Using strings for commentation has the following (potential) disadvantages:
It confuses people who don't know that the string does nothing.
Comments and string literals are highlighted differently in code editors, so your style may make your code harder to read.
It might affect performance and/or memory usage (if the strings are not removed during bytecode compilation, removing comments is done on the scanner level so it's definitively cheaper)
Most important for Python programmers: It is not pythonic:
There should be one—and preferably only one—obvious way to do it.
Stick to the standards, use comments.
I think that only the first string literal in a definition (or class) is "special", i.e. gets stored by the interpreter into the defined object's (or class') docstring.
Any other string literals you place in the code will, at the worst, mean the interpreter will build the string value at run-time, and then just throw it away. This means that doing "comments" by littering the code with string constants might cost, performance-wise.
Of course, I have not benchmarked this, and also don't know the Python interpreter well enough to say for sure.
The disadvantage, of course, is that someone else reading it will find that the code strings and comment strings are interleaved, which could be confusing.