标签归档:code-formatting

如何在Python中打破这条漫长的路线?

问题:如何在Python中打破这条漫长的路线?

您将如何格式化这样的长行?我希望宽度不超过80个字符:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

这是我最好的选择吗?

url = "Skipping {0} because its thumbnail was already in our system as {1}."
logger.info(url.format(line[indexes['url']], video.title))

How would you go about formatting a long line such as this? I’d like to get it to no more than 80 characters wide:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

Is this my best option?

url = "Skipping {0} because its thumbnail was already in our system as {1}."
logger.info(url.format(line[indexes['url']], video.title))

回答 0

那是一个开始。在使用长字符串的代码之外定义较长的字符串并不是一个坏习惯。这是分离数据和行为的一种方式。您的第一个选择是通过使字符串文字彼此相邻来隐式地将它们连接在一起:

("This is the first line of my text, "
"which will be joined to a second.")

或使用行尾连续符,这会更脆弱一些,因为这可行:

"This is the first line of my text, " \
"which will be joined to a second."

但这不是:

"This is the first line of my text, " \ 
"which will be joined to a second."

看到不同?没有?好吧,当它是您的代码时,您也不会。

隐式连接的不利之处在于,它仅适用于字符串文字,而不适用于从变量中提取的字符串,因此在进行重构时,事情可能会变得更加复杂。另外,您只能对整个组合字符串进行插值格式化。

另外,您可以使用串联运算符(+)显式加入:

("This is the first line of my text, " + 
"which will be joined to a second.")

正如zen python所说的那样,显式比隐式更好,但这会创建三个字符串而不是一个字符串,并且使用两倍的内存:您已经编写了两个字符串,再加上一个字符串,即两个字符串连接在一起,所以您必须知道何时忽略禅宗。好处是您可以将格式分别应用于每一行中的任何子字符串,也可以应用于位于括号外的全部子字符串。

最后,您可以使用三引号引起来的字符串:

"""This is the first line of my text
which will be joined to a second."""

这通常是我的最爱,尽管它的行为略有不同,因为换行符和后续行中的任何前导空格都会显示在您的最终字符串中。您可以使用转义的反斜杠消除换行符。

"""This is the first line of my text \
which will be joined to a second."""

这具有与上述相同技术相同的问题,因为正确的代码与不正确的代码的区别仅在于不可见的空格。

哪一个“最佳”取决于您的特定情况,但答案不只是简单的美学,而是微妙的不同行为之一。

That’s a start. It’s not a bad practice to define your longer strings outside of the code that uses them. It’s a way to separate data and behavior. Your first option is to join string literals together implicitly by making them adjacent to one another:

("This is the first line of my text, "
"which will be joined to a second.")

Or with line ending continuations, which is a little more fragile, as this works:

"This is the first line of my text, " \
"which will be joined to a second."

But this doesn’t:

"This is the first line of my text, " \ 
"which will be joined to a second."

See the difference? No? Well you won’t when it’s your code either.

The downside to implicit joining is that it only works with string literals, not with strings taken from variables, so things can get a little more hairy when you refactor. Also, you can only interpolate formatting on the combined string as a whole.

Alternatively, you can join explicitly using the concatenation operator (+):

("This is the first line of my text, " + 
"which will be joined to a second.")

Explicit is better than implicit, as the zen of python says, but this creates three strings instead of one, and uses twice as much memory: there are the two you have written, plus one which is the two of them joined together, so you have to know when to ignore the zen. The upside is you can apply formatting to any of the substrings separately on each line, or to the whole lot from outside the parentheses.

Finally, you can use triple-quoted strings:

"""This is the first line of my text
which will be joined to a second."""

This is often my favorite, though its behavior is slightly different as the newline and any leading whitespace on subsequent lines will show up in your final string. You can eliminate the newline with an escaping backslash.

"""This is the first line of my text \
which will be joined to a second."""

This has the same problem as the same technique above, in that correct code only differs from incorrect code by invisible whitespace.

Which one is “best” depends on your particular situation, but the answer is not simply aesthetic, but one of subtly different behaviors.


回答 1

连续字符串文字由编译器连接,带括号的表达式被视为单行代码:

logger.info("Skipping {0} because it's thumbnail was "
  "already in our system as {1}.".format(line[indexes['url']],
  video.title))

Consecutive string literals are joined by the compiler, and parenthesized expressions are considered to be a single line of code:

logger.info("Skipping {0} because it's thumbnail was "
  "already in our system as {1}.".format(line[indexes['url']],
  video.title))

回答 2

我个人不喜欢挂空块,所以我将其格式化为:

logger.info(
    'Skipping {0} because its thumbnail was already in our system as {1}.'
    .format(line[indexes['url']], video.title)
)

通常,我不会太费力地使代码完全适合80列行。可以将线长降低到合理的水平,但是硬80的限制已成过去。

Personally I dislike hanging open blocks, so I’d format it as:

logger.info(
    'Skipping {0} because its thumbnail was already in our system as {1}.'
    .format(line[indexes['url']], video.title)
)

In general I wouldn’t bother struggle too hard to make code fit exactly within a 80-column line. It’s worth keeping line length down to reasonable levels, but the hard 80 limit is a thing of the past.


回答 3

您可以使用textwrap模块将其分成多行

import textwrap
str="ABCDEFGHIJKLIMNO"
print("\n".join(textwrap.wrap(str,8)))

ABCDEFGH
IJKLIMNO

文档中

文本换行。wrap(text [,width [,…]])
将单个段落包装在文本(字符串)中,因此每一行最多为宽度字符。返回输出行列表,不带最终换行符。

可选的关键字参数与的实例属性相对应TextWrapper,如下所述。宽度默认为70

有关TextWrapper.wrap()wrap()行为的更多详细信息,请参见方法。

You can use textwrap module to break it in multiple lines

import textwrap
str="ABCDEFGHIJKLIMNO"
print("\n".join(textwrap.wrap(str,8)))

ABCDEFGH
IJKLIMNO

From the documentation:

textwrap.wrap(text[, width[, …]])
Wraps the single paragraph in text (a string) so every line is at most width characters long. Returns a list of output lines, without final newlines.

Optional keyword arguments correspond to the instance attributes of TextWrapper, documented below. width defaults to 70.

See the TextWrapper.wrap() method for additional details on how wrap() behaves.


回答 4

对于也尝试调用.format()长字符串并且在不中断后续.format(调用的情况下无法使用某些最受欢迎的字符串包装技术的任何人,您可以使用str.format("", 1, 2)代替"".format(1, 2)。这使您可以使用任何喜欢的技术来断开字符串。例如:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

logger.info(str.format(("Skipping {0} because its thumbnail was already"
+ "in our system as {1}"), line[indexes['url']], video.title))

否则,唯一的可能性就是使用行尾延续,我个人并不喜欢。

For anyone who is also trying to call .format() on a long string, and is unable to use some of the most popular string wrapping techniques without breaking the subsequent .format( call, you can do str.format("", 1, 2) instead of "".format(1, 2). This lets you break the string with whatever technique you like. For example:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

can be

logger.info(str.format(("Skipping {0} because its thumbnail was already"
+ "in our system as {1}"), line[indexes['url']], video.title))

Otherwise, the only possibility is using line ending continuations, which I personally am not a fan of.


在Python中格式化多行字典的正确方法是什么?

问题:在Python中格式化多行字典的正确方法是什么?

在Python中,我想在代码中编写多行字典。有几种方法可以格式化它。我想到的是一些:

  1. mydict = { "key1": 1,
               "key2": 2,
               "key3": 3, }
  2. mydict = { "key1": 1,
               "key2": 2,
               "key3": 3,
             }
  3. mydict = {
        "key1": 1,
        "key2": 2,
        "key3": 3,
    }

我知道以上任何一种在语法上都是正确的,但是我假设Python字典有一种首选的缩进和换行样式。它是什么?

注意:这不是语法问题。就我所知,以上所有都是有效的Python语句,并且彼此等效。

In Python, I want to write a multi-line dict in my code. There are a couple of ways one could format it. Here are a few that I could think of:

  1. mydict = { "key1": 1,
               "key2": 2,
               "key3": 3, }
    
  2. mydict = { "key1": 1,
               "key2": 2,
               "key3": 3,
             }
    
  3. mydict = {
        "key1": 1,
        "key2": 2,
        "key3": 3,
    }
    

I know that any of the above is syntactically correct, but I assume that there is one preferred indentation and line-break style for Python dicts. What is it?

Note: This is not an issue of syntax. All of the above are (as far as I know) valid Python statements and are equivalent to each other.


回答 0

我使用#3。长列表,元组等也是如此。不需要在缩进之外添加任何额外的空格。一如既往,保持一致。

mydict = {
    "key1": 1,
    "key2": 2,
    "key3": 3,
}

mylist = [
    (1, 'hello'),
    (2, 'world'),
]

nested = {
    a: [
        (1, 'a'),
        (2, 'b'),
    ],
    b: [
        (3, 'c'),
        (4, 'd'),
    ],
}

同样,这是在不引入任何空格的情况下包括大字符串的我的首选方式(例如,如果使用三引号的多行字符串,则会得到此信息):

data = (
    "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABG"
    "l0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEN"
    "xBRpFYmctaKCfwrBSCrRLuL3iEW6+EEUG8XvIVjYWNgJdhFjIX"
    "rz6pKtPB5e5rmq7tmxk+hqO34e1or0yXTGrj9sXGs1Ib73efh1"
    "AAAABJRU5ErkJggg=="
)

I use #3. Same for long lists, tuples, etc. It doesn’t require adding any extra spaces beyond the indentations. As always, be consistent.

mydict = {
    "key1": 1,
    "key2": 2,
    "key3": 3,
}

mylist = [
    (1, 'hello'),
    (2, 'world'),
]

nested = {
    a: [
        (1, 'a'),
        (2, 'b'),
    ],
    b: [
        (3, 'c'),
        (4, 'd'),
    ],
}

Similarly, here’s my preferred way of including large strings without introducing any whitespace (like you’d get if you used triple-quoted multi-line strings):

data = (
    "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABG"
    "l0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEN"
    "xBRpFYmctaKCfwrBSCrRLuL3iEW6+EEUG8XvIVjYWNgJdhFjIX"
    "rz6pKtPB5e5rmq7tmxk+hqO34e1or0yXTGrj9sXGs1Ib73efh1"
    "AAAABJRU5ErkJggg=="
)

回答 1

首先,就像史蒂文·鲁姆巴尔斯基(Steven Rumbalski)所说的那样,“ PEP8不能解决这个问题”,因此这是个人喜好问题。

我将使用与您的格式3类似但不完全相同的格式。这是我的,以及原因。

my_dictionary = { # Don't think dict(...) notation has more readability
    "key1": 1, # Indent by one press of TAB (i.e. 4 spaces)
    "key2": 2, # Same indentation scale as above
    "key3": 3, # Keep this final comma, so that future addition won't show up as 2-lines change in code diff
    } # My favorite: SAME indentation AS ABOVE, to emphasize this bracket is still part of the above code block!
the_next_line_of_code() # Otherwise the previous line would look like the begin of this part of code

bad_example = {
               "foo": "bar", # Don't do this. Unnecessary indentation wastes screen space
               "hello": "world" # Don't do this. Omitting the comma is not good.
} # You see? This line visually "joins" the next line when in a glance
the_next_line_of_code()

btw_this_is_a_function_with_long_name_or_with_lots_of_parameters(
    foo='hello world',  # So I put one parameter per line
    bar=123,  # And yeah, this extra comma here is harmless too;
              # I bet not many people knew/tried this.
              # Oh did I just show you how to write
              # multiple-line inline comment here?
              # Basically, same indentation forms a natural paragraph.
    ) # Indentation here. Same idea as the long dict case.
the_next_line_of_code()

# By the way, now you see how I prefer inline comment to document the very line.
# I think this inline style is more compact.
# Otherwise you will need extra blank line to split the comment and its code from others.

some_normal_code()

# hi this function is blah blah
some_code_need_extra_explanation()

some_normal_code()

First of all, like Steven Rumbalski said, “PEP8 doesn’t address this question”, so it is a matter of personal preference.

I would use a similar but not identical format as your format 3. Here is mine, and why.

my_dictionary = { # Don't think dict(...) notation has more readability
    "key1": 1, # Indent by one press of TAB (i.e. 4 spaces)
    "key2": 2, # Same indentation scale as above
    "key3": 3, # Keep this final comma, so that future addition won't show up as 2-lines change in code diff
    } # My favorite: SAME indentation AS ABOVE, to emphasize this bracket is still part of the above code block!
the_next_line_of_code() # Otherwise the previous line would look like the begin of this part of code

bad_example = {
               "foo": "bar", # Don't do this. Unnecessary indentation wastes screen space
               "hello": "world" # Don't do this. Omitting the comma is not good.
} # You see? This line visually "joins" the next line when in a glance
the_next_line_of_code()

btw_this_is_a_function_with_long_name_or_with_lots_of_parameters(
    foo='hello world',  # So I put one parameter per line
    bar=123,  # And yeah, this extra comma here is harmless too;
              # I bet not many people knew/tried this.
              # Oh did I just show you how to write
              # multiple-line inline comment here?
              # Basically, same indentation forms a natural paragraph.
    ) # Indentation here. Same idea as the long dict case.
the_next_line_of_code()

# By the way, now you see how I prefer inline comment to document the very line.
# I think this inline style is more compact.
# Otherwise you will need extra blank line to split the comment and its code from others.

some_normal_code()

# hi this function is blah blah
some_code_need_extra_explanation()

some_normal_code()

回答 2

由于您的键是字符串,并且因为我们在谈论可读性,所以我更喜欢:

mydict = dict(
    key1 = 1,
    key2 = 2,
    key3 = 3,
)

Since your keys are strings and since we are talking about readability, I prefer :

mydict = dict(
    key1 = 1,
    key2 = 2,
    key3 = 3,
)

回答 3

通常,如果您有大型python对象,则很难格式化它们。我个人更喜欢为此使用一些工具。

这是python-beautifier-www.cleancss.com/python-beautify,可立即将您的数据转换为可自定义的样式。

Usually, if you have big python objects it’s quite hard to format them. I personally prefer using some tools for that.

Here is python-beautifier – www.cleancss.com/python-beautify that instantly turns your data into customizable style.


回答 4

dict(rank = int(lst[0]),
                grade = str(lst[1]),
                channel=str(lst[2])),
                videos = float(lst[3].replace(",", " ")),
                subscribers = float(lst[4].replace(",", "")),
                views = float(lst[5].replace(",", "")))
dict(rank = int(lst[0]),
                grade = str(lst[1]),
                channel=str(lst[2])),
                videos = float(lst[3].replace(",", " ")),
                subscribers = float(lst[4].replace(",", "")),
                views = float(lst[5].replace(",", "")))

回答 5

根据我在教程和其他方面的经验,似乎总是首选2号,但这是个人喜好选择,而不是其他任何事情。

From my experience with tutorials, and other things number 2 always seems preferred, but it’s a personal preference choice more than anything else.


回答 6

通常,您不会在最后一个输入项后加入逗号,但Python会为您更正。

Generally, you would not include the comma after the final entry, but Python will correct that for you.