Triple-double quote v.s. Double quote - python

What is the preferred way to write Python doc string?
""" or "
In the book Dive Into Python, the author provides the following example:
def buildConnectionString(params):
"""Build a connection string from a dictionary of parameters.
Returns string."""
In another chapter, the author provides another example:
def stripnulls(data):
"strip whitespace and nulls"
return data.replace("\00", "").strip()
Both syntax work. The only difference to me is that """ allows us to write multi-line doc.
Are there any differences other than that?

From the PEP8 Style Guide:
PEP 257 describes good docstring conventions. Note that most
importantly, the """ that ends a multiline docstring should be on a
line by itself, e.g.:
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
For one liner docstrings, it's okay to keep the closing """ on the
same line.
PEP 257 recommends using triple quotes, even for one-line docstrings:
Triple quotes are used even though the string fits on one line. This
makes it easy to later expand it.
Note that not even the Python standard library itself follows these recommendations consistently. For example,
abcoll.py
ftplib.py
functools.py
inspect.py

They're both strings, so there is no difference. The preferred style is triple double quotes (PEP 257):
For consistency, always use """triple double quotes""" around docstrings.
Use r"""raw triple double quotes""" if you use any backslashes in your docstrings. For Unicode docstrings, use u"""Unicode triple-quoted strings""".

No, not really. If you are writing to a file, using triple quotes may be ideal, because you don't have to use "\n" in order to go a line down. Just make sure the quotes you start and end with are the same type(Double or Triple quotes). Here is a reliable resource if you have any more questions:
http://docs.python.org/release/1.5.1p1/tut/strings.html

You can also use triple-double quotes for a long SQL query to improve the readability and not to scroll right to see it as shown below:
query = """
SELECT count(*)
FROM (SELECT *
FROM student
WHERE grade = 2 AND major = 'Computer Science'
FOR UPDATE)
AS result;
"""
And, if using double quotes for the SQL query above, the readability is worse and you will need to scroll right to see it as shown below:
query = "SELECT count(*) FROM (SELECT * FROM student WHERE grade = 2 AND major = 'Computer Science' FOR UPDATE) AS result;"
In addition, you can also use triple-double quotes for a GraphQL query as shown below:
query = """
{
products(first: 5) {
edges {
node {
id
handle
}
}
}
}"""

Related

In Python 3.5, how are triple quotes (""") considered comments by the IDE?

My CS teacher told me that """ triple quotations are used as comments, yet I learned it as strings with line-breaks and indentations. This got me thinking about - does python completely triple quote lines outside of relevant statements?
"""is this completely ignored like a comment"""
-or, is the computer actually considering this?
Triple quoted strings are used as comment by many developers but it is actually not a comment, it is similar to regular strings in python but it allows the string to be in multi-line. You will find no official reference for triple quoted strings to be a comment.
In python, there is only one type of comment that starts with hash # and can contain only a single line of text.
According to PEP 257, it can however be used as a docstring, which is again not really a comment.
def foo():
"""
Developer friendly text for describing the purpose of function
Some test cases used by different unit testing libraries
"""
<body of the function>
You can just assign them to a variable as you do with single quoted strings:
x = """a multi-line text
enclosed by
triple quotes
"""
Furthermore, if you try in repl, triple quoted strings get printed, had it really been a comment, should it have been printed?:
>>> #comment
>>> """triple quoted"""
'triple quoted'
As someone else already pointed out, they are indeed strings and not comments in Python. I just wanted to add a little more context about your question of "is the computer actually considering it?"
The answer is yes, since it isn't a comment. Take the below code for example:
def my_func():
"""
Some string
"""
print("Hello World!")
my_func()
Trying to run this will actually produce a syntax error because of the indentation.
So as far as I know, triple quotes can be used for both purposes but # is the standard for commenting.
According to this website, what I can understand is that ''' This '''
can be used as a comment and because they are handled as docstrings technically (not tested) ' This ' can also act as a comment depending on where put it. However, even though single and triple quotes can be used as comments, it does not mean that they are comments. For example, # comments are compeletely ignored by the interpreter whereas ''' comments might be loaded into memory (just a probable guess, not confirmed). But from what I can tell, they aren't handled as comments as shown below:
So they are not but they can be used as comments. Generally speaking, use #.
EDIT:
As #BTables pointed out, you will get an indentation error if you don't indent them correctly. So they are indeed handled as strings.

Pretty-print Lisp using Python

Is there a way to pretty-print Lisp-style code string (in other words, a bunch of balanced parentheses and text within) in Python without re-inventing a wheel?
Short answer
I think a reasonable approach, if you can, is to generate Python lists or custom objects instead of strings and use the pprint module, as suggested by #saulspatz.
Long answer
The whole question look like an instance of an XY-problem. Why? because you are using Python (why not Lisp?) to manipulate strings (why not data-structures?) representing generated Lisp-style code, where Lisp-style is defined as "a bunch of parentheses and text within".
To the question "how to pretty-print?", I would thus respond "I wouldn't start from here!".
The best way to not reinvent the wheel in your case, apart from using existing wheels, is to stick to a simple output format.
But first of all all, why do you need to pretty-print? who will look at the resulting code?
Depending on the exact Lisp dialect you are using and the intended usage of the code, you could format your code very differently. Think about newlines, indentation and maximum width of your text, for example. The Common Lisp pretty-printer is particulary evolved and I doubt you want to have the same level of configurability.
If you used Lisp, a simple call to pprint would solve your problem, but you are using Python, so stick with the most reasonable output for the moment because pretty-printing is a can of worms.
If your code is intended for human readers, please:
don't put closing parenthesis on their own lines
don't vertically align open and close parenthesis
don't add spaces between opening parenthesis
This is ugly:
( * ( + 3 x )
(f
x
y
)
)
This is better:
(* (+ 3 x)
(f x y))
Or simply:
(* (+ 3 x) (f x y))
See here for more details.
But before printing, you have to parse your input string and make sure it is well-formed. Maybe you are sure it is well-formed, due to how you generate your forms, but I'd argue that the printer should ignore that and not make too many assumptions. If you passed the pretty-printer an AST represented by Python objects instead of just strings, this would be easier, as suggested in comments. You could build a data-structure or custom classes and use the pprint (python) module. That, as said above, seems to be the way to go in your case, if you can change how you generate your Lisp-style code.
With strings, you are supposed to handle any possible input and reject invalid ones.
This means checking that parenthesis and quotes are balanced (beware of escape characters), etc.
Actually, you don't need to really build an intermediate tree for printing (though it would probably help for other parts of your program), because Lisp-style code is made of forms that are easily nested and use a prefix notation: you can scan your input string from left-to-right and print as required when seeing parenthesis (open parenthesis: recurse; close parenthesis, return from recursion). When you first encounter an unescaped double-quote ", read until the next one ", ...
This, coupled with a simple printing method, could be sufficient for your needs.
I think the easiest method would be to use triple quotations. If you say:
print """
(((This is some lisp code))) """
It should work.
You can format your code any way you like within the triple quotes and it will come out the way you want it to.
Best of luck and happy coding!
I made this rudimentary pretty printer once for prettifying CLIPS, which is based on Lisp. Might help:
def clips_pprint(clips_str: str) -> str:
"""Pretty-prints a CLIPS string.
Indents a CLIPS string for easier visual confirmation during development
and verification.
Assumes the CLIPS string is valid CLIPS, i.e. braces are paired.
"""
LB = "("
RB = ")"
TAB = " " * 4
formatted_clips_str = ""
tab_count = 0
for c in clips_str:
if c == LB:
formatted_clips_str += os.linesep
for _i in range(tab_count):
formatted_clips_str += TAB
tab_count += 1
elif c == RB:
tab_count -= 1
formatted_clips_str += c
return formatted_clips_str.strip()

Modgrammar defining nested strings in python

I need to define Strings for a custom language parser. I am using modgrammar to define this language parser. This language (sqf) has a datatype String which allows for nesting.
A string is denoted by the standard double quotes ("), a string within a string is denoted by two sets of double quotes example.
"this is a string ""this is a string within a string"""
As far as i am aware there is no limit as to the levels of nesting.
So far i have tried the following to parse strings:
from modgrammar import *
class String (Grammar):
grammar = (
(L("\""), ANY_EXCEPT("\""), (L("\"")),
(
OPTIONAL((L("\""),
REF("String"),
(L("\""))
)
)
String.grammar_resolve_refs()
And
class String (Grammar):
grammar = (
(L("\""),
ANY_EXCEPT("\""),
(L("\"")
)
class StringNested (Grammar):
grammar = (String,OPTIONAL((L("\""),REF("StringNested"),(L("\""))
)
and:
class StringBase (Grammar):
grammar_greedy = True
grammar = (REPEAT(WORD("A-Za-z0-9")))
class String (Grammar):
# grammar =(OR(
# OR((StringBase,LITERAL('"'),StringBase, LITERAL('"')), (LITERAL('"'),StringBase,LITERAL('"'),StringBase) ),
# StringBase,
# ))
grammar = L('"'),OPTIONAL(L('"'),StringBase,L('"')), OPTIONAL(LITERAL('"'),L('"'),REF("String"), LITERAL('"'),L('"')), (StringBase),L('"')
neither of these seem to be working.
edit: using python 3.4 and modgrammar 0.10
edit 2: NOTE:
I have found that while mod grammar is powerful and good at what it does it may not be the right solution my problem, I found that a hand coded linear parsing was much more efficient at parsing data in this instance data provided is already programmic output and therefor unlikely to contain errors in a way that would require such extensive testing as modgrammar allows.
So I finally found a solution that seems to work (pending extensive testing).
The answer can be found here:
Google Groups: Parsing Escaped Characters
posted by Dan S:
Dan S
08/09/2012
Found one way:
grammar = ('"', ZERO_OR_MORE(WORD('^"') | WORD('^\', '"', count=2)), '"')

arcpy query not working

I have an ArcPy script that is meant to select the desired attributes (both E-dom and E-subdom – see example below) from an attribute table based on a query.
myQuery = '"VM_POLY" = \'E-dom\'' or '"VM_POLY" = \'E-subdom\''
myInputShapeFile = r"D:\FieldStudy.shp"
myOutputShapefile = r"D:\Endangered.shp"
arcpy.Select_analysis(myInputShapeFile, myOutputShapefile, myQuery)
When the script is finished, only one type of attribute from the query is selected. In the attribute table for myInputShapeFile, there is both E-dom and E-subdom attributes, but the script will only return E-dom in the myOutputShapefile. I know the problem is possibly in the query (myQuery) but I am not sure how to resolve it.
If someone could provide some guidance, it would greatly be appreciated.
Could it be that you got your apostrophes wrong?
myQuery = '"VM_POLY" = \'E-dom\'' or '"VM_POLY" = \'E-subdom\''
# ^ ¨ ¨^ ^ ¨ ¨^
(Apostrophes marked by a ^ delimit a Python string; those marked with ¨ are escaped and therefore part of the string.)
I suppose your query ought to be:
myQuery = '"VM_POLY" = \'E-dom\' or "VM_POLY" = \'E-subdom\''
# ^ ¨ ¨ ¨ ¨^
because the or should not be interpreted by Python (logical operator applied to two strings), but should be part of the query text.
Python string formatting (and the SQL "IN" operator) make it (slightly) easier to handle the complex quote syntax:
myQuery = "\"{}\" IN ('{}', '{}')".format("VM_POLY", "E-dom", "E-subdom")
I would simplify your query with specifiers.
myQuery = ' "%s" = %s or "%s" = %s ' %('VM_POLY','E-dom','VM_POLY','E-subdom')
I know it seems quirky at first but its a good way to ensure your quotes and double quotes are positioned correctly for such things that require specific formatting. They have become my best friend as of late.
NOTE: if you have numbers you would like to inject into the string you can do so by using %d instead of %s.
Try this:
myQuery = '"VM_POLY" = "E-dom" or "VM_POLY"= "E-subdom"'
As was stated the or operator was being mishandled because it was not within the confines of your quotation. You also had the escape character \ in there which probably was not needed but you were attempting to work around the fact that your or operator was exposed and not part of the SQL query and thus picked up by the Python interpreter instead.

Why does python use unconventional triple-quotation marks for comments?

Why didn't python just use the traditional style of comments like C/C++/Java uses:
/**
* Comment lines
* More comment lines
*/
// line comments
// line comments
//
Is there a specific reason for this or is it just arbitrary?
Python doesn't use triple quotation marks for comments. Comments use the hash (a.k.a. pound) character:
# this is a comment
The triple quote thing is a doc string, and, unlike a comment, is actually available as a real string to the program:
>>> def bla():
... """Print the answer"""
... print 42
...
>>> bla.__doc__
'Print the answer'
>>> help(bla)
Help on function bla in module __main__:
bla()
Print the answer
It's not strictly required to use triple quotes, as long as it's a string. Using """ is just a convention (and has the advantage of being multiline).
A number of the answers got many of the points, but don't give the complete view of how things work. To summarize...
# comment is how Python does actual comments (similar to bash, and some other languages). Python only has "to the end of the line" comments, it has no explicit multi-line comment wrapper (as opposed to javascript's /* .. */). Most Python IDEs let you select-and-comment a block at a time, this is how many people handle that situation.
Then there are normal single-line python strings: They can use ' or " quotation marks (eg 'foo' "bar"). The main limitation with these is that they don't wrap across multiple lines. That's what multiline-strings are for: These are strings surrounded by triple single or double quotes (''' or """) and are terminated only when a matching unescaped terminator is found. They can go on for as many lines as needed, and include all intervening whitespace.
Either of these two string types define a completely normal string object. They can be assigned a variable name, have operators applied to them, etc. Once parsed, there are no differences between any of the formats. However, there are two special cases based on where the string is and how it's used...
First, if a string just written down, with no additional operations applied, and not assigned to a variable, what happens to it? When the code executes, the bare string is basically discarded. So people have found it convenient to comment out large bits of python code using multi-line strings (providing you escape any internal multi-line strings). This isn't that common, or semantically correct, but it is allowed.
The second use is that any such bare strings which follow immediately after a def Foo(), class Foo(), or the start of a module, are treated as string containing documentation for that object, and stored in the __doc__ attribute of the object. This is the most common case where strings can seem like they are a "comment". The difference is that they are performing an active role as part of the parsed code, being stored in __doc__... and unlike a comment, they can be read at runtime.
Triple-quotes aren't comments. They're string literals that span multiple lines and include those line breaks in the resulting string. This allows you to use
somestr = """This is a rather long string containing
several lines of text just as you would do in C.
Note that whitespace at the beginning of the line is\
significant."""
instead of
somestr = "This is a rather long string containing\n\
several lines of text just as you would do in C.\n\
Note that whitespace at the beginning of the line is\
significant."
Most scripting languages use # as a comment marker so to skip automatically the shebang (#!) which specifies to the program loader the interpreter to run (like in #!/bin/bash). Alternatively, the interpreter could be instructed to automatically skip the first line, but it's way more convenient just to define # as comment marker and that's it, so it's skipped as a consequence.
Guido - the creator of Python, actually weighs in on the topic here:
https://twitter.com/gvanrossum/status/112670605505077248?lang=en
In summary - for multiline comments, just use triple quotes. For academic purposes - yes it technically is a string, but it gets ignored because it is never used or assigned to a variable.

Categories

Resources