标签归档:indentation

一行Python代码可以知道其缩进嵌套级别吗?

问题:一行Python代码可以知道其缩进嵌套级别吗?

从这样的事情:

print(get_indentation_level())

    print(get_indentation_level())

        print(get_indentation_level())

我想得到这样的东西:

1
2
3

代码可以这样读取吗?

我想要的只是更多嵌套代码部分的输出。以使代码易于阅读的方式,使输出易于阅读。

当然,我可以使用eg手动实现此功能.format(),但是我想到的是自定义打印功能,该功能print(i*' ' + string)在哪里i是缩进级别。这将是使终端上的输出可读的一种快速方法。

有没有更好的方法可以避免麻烦的手动格式化?

From something like this:

print(get_indentation_level())

    print(get_indentation_level())

        print(get_indentation_level())

I would like to get something like this:

1
2
3

Can the code read itself in this way?

All I want is the output from the more nested parts of the code to be more nested. In the same way that this makes code easier to read, it would make the output easier to read.

Of course I could implement this manually, using e.g. .format(), but what I had in mind was a custom print function which would print(i*' ' + string) where i is the indentation level. This would be a quick way to make readable output on my terminal.

Is there a better way to do this which avoids painstaking manual formatting?


回答 0

如果您想缩进而不是使用空格和制表符来嵌套级别,那么事情就会变得棘手。例如,在以下代码中:

if True:
    print(
get_nesting_level())

get_nesting_level尽管实际上在行的行上没有前导空格,但对的调用实际上嵌套了一层深度get_nesting_level呼叫。同时,在以下代码中:

print(1,
      2,
      get_nesting_level())

调用 get_nesting_level尽管该行中存在领先的空格,对仍嵌套在零级深度。

在下面的代码中:

if True:
  if True:
    print(get_nesting_level())

if True:
    print(get_nesting_level())

两次调用 get_nesting_level尽管前导空白是相同的,但这处于不同的嵌套级别。

在下面的代码中:

if True: print(get_nesting_level())

是嵌套的零级,还是一级?在INDENTDEDENT形式语法中标记,深度为零,但是您可能会感觉不一样。


如果要执行此操作,则必须标记整个文件,直到调用,计数INDENTDEDENT标记为止。该tokenize模块对于此类功能非常有用:

import inspect
import tokenize

def get_nesting_level():
    caller_frame = inspect.currentframe().f_back
    filename, caller_lineno, _, _, _ = inspect.getframeinfo(caller_frame)
    with open(filename) as f:
        indentation_level = 0
        for token_record in tokenize.generate_tokens(f.readline):
            token_type, _, (token_lineno, _), _, _ = token_record
            if token_lineno > caller_lineno:
                break
            elif token_type == tokenize.INDENT:
                indentation_level += 1
            elif token_type == tokenize.DEDENT:
                indentation_level -= 1
        return indentation_level

If you want indentation in terms of nesting level rather than spaces and tabs, things get tricky. For example, in the following code:

if True:
    print(
get_nesting_level())

the call to get_nesting_level is actually nested one level deep, despite the fact that there is no leading whitespace on the line of the get_nesting_level call. Meanwhile, in the following code:

print(1,
      2,
      get_nesting_level())

the call to get_nesting_level is nested zero levels deep, despite the presence of leading whitespace on its line.

In the following code:

if True:
  if True:
    print(get_nesting_level())

if True:
    print(get_nesting_level())

the two calls to get_nesting_level are at different nesting levels, despite the fact that the leading whitespace is identical.

In the following code:

if True: print(get_nesting_level())

is that nested zero levels, or one? In terms of INDENT and DEDENT tokens in the formal grammar, it’s zero levels deep, but you might not feel the same way.


If you want to do this, you’re going to have to tokenize the whole file up to the point of the call and count INDENT and DEDENT tokens. The tokenize module would be very useful for such a function:

import inspect
import tokenize

def get_nesting_level():
    caller_frame = inspect.currentframe().f_back
    filename, caller_lineno, _, _, _ = inspect.getframeinfo(caller_frame)
    with open(filename) as f:
        indentation_level = 0
        for token_record in tokenize.generate_tokens(f.readline):
            token_type, _, (token_lineno, _), _, _ = token_record
            if token_lineno > caller_lineno:
                break
            elif token_type == tokenize.INDENT:
                indentation_level += 1
            elif token_type == tokenize.DEDENT:
                indentation_level -= 1
        return indentation_level

回答 1

是的,绝对有可能,这是一个可行的示例:

import inspect

def get_indentation_level():
    callerframerecord = inspect.stack()[1]
    frame = callerframerecord[0]
    info = inspect.getframeinfo(frame)
    cc = info.code_context[0]
    return len(cc) - len(cc.lstrip())

if 1:
    print get_indentation_level()
    if 1:
        print get_indentation_level()
        if 1:
            print get_indentation_level()

Yeah, that’s definitely possible, here’s a working example:

import inspect

def get_indentation_level():
    callerframerecord = inspect.stack()[1]
    frame = callerframerecord[0]
    info = inspect.getframeinfo(frame)
    cc = info.code_context[0]
    return len(cc) - len(cc.lstrip())

if 1:
    print get_indentation_level()
    if 1:
        print get_indentation_level()
        if 1:
            print get_indentation_level()

回答 2

您可以使用sys.current_frame.f_lineno以获取行号。然后,为了找到压痕级别的数量,您需要找到压痕为零的前一行,然后从该行的数量中减去当前行号,您将获得压痕数量:

import sys
current_frame = sys._getframe(0)

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()
    current_line_no = current_frame.f_lineno
    to_current = lines[:current_line_no]
    previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
    return current_line_no - previous_zoro_ind

演示:

if True:
    print get_ind_num()
    if True:
        print(get_ind_num())
        if True:
            print(get_ind_num())
            if True: print(get_ind_num())
# Output
1
3
5
6

如果您想要基于先前行的缩进级别编号,:则只需稍作更改即可:

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()

    current_line_no = current_frame.f_lineno
    to_current = lines[:current_line_no]
    previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
    return sum(1 for line in lines[previous_zoro_ind-1:current_line_no] if line.strip().endswith(':'))

演示:

if True:
    print get_ind_num()
    if True:
        print(get_ind_num())
        if True:
            print(get_ind_num())
            if True: print(get_ind_num())
# Output
1
2
3
3

作为替代答案,这里是一个用于获取缩进数量(空格)的函数:

import sys
from itertools import takewhile
current_frame = sys._getframe(0)

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()
    return sum(1 for _ in takewhile(str.isspace, lines[current_frame.f_lineno - 1]))

You can use sys.current_frame.f_lineno in order to get the line number. Then in order to find the number of indentation level you need to find the previous line with zero indentation then be subtracting the current line number from that line’s number you’ll get the number of indentation:

import sys
current_frame = sys._getframe(0)

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()
    current_line_no = current_frame.f_lineno
    to_current = lines[:current_line_no]
    previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
    return current_line_no - previous_zoro_ind

Demo:

if True:
    print get_ind_num()
    if True:
        print(get_ind_num())
        if True:
            print(get_ind_num())
            if True: print(get_ind_num())
# Output
1
3
5
6

If you want the number of the indentation level based on the previouse lines with : you can just do it with a little change:

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()

    current_line_no = current_frame.f_lineno
    to_current = lines[:current_line_no]
    previous_zoro_ind = len(to_current) - next(i for i, line in enumerate(to_current[::-1]) if not line[0].isspace())
    return sum(1 for line in lines[previous_zoro_ind-1:current_line_no] if line.strip().endswith(':'))

Demo:

if True:
    print get_ind_num()
    if True:
        print(get_ind_num())
        if True:
            print(get_ind_num())
            if True: print(get_ind_num())
# Output
1
2
3
3

And as an alternative answer here is a function for getting the number of indentation (whitespace):

import sys
from itertools import takewhile
current_frame = sys._getframe(0)

def get_ind_num():
    with open(__file__) as f:
        lines = f.readlines()
    return sum(1 for _ in takewhile(str.isspace, lines[current_frame.f_lineno - 1]))

回答 3

为了解决导致您提出问题的“实际”问题,您可以实现一个contextmanager,它可以跟踪缩进级别并使with代码中的块结构与输出的缩进级别相对应。这样,代码缩进仍然可以反映输出缩进,而不会造成过多的耦合。仍然可以将代码重构为不同的功能,并基于代码结构使用其他缩进,而不会干扰输出缩进。

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function


class IndentedPrinter(object):

    def __init__(self, level=0, indent_with='  '):
        self.level = level
        self.indent_with = indent_with

    def __enter__(self):
        self.level += 1
        return self

    def __exit__(self, *_args):
        self.level -= 1

    def print(self, arg='', *args, **kwargs):
        print(self.indent_with * self.level + str(arg), *args, **kwargs)


def main():
    indented = IndentedPrinter()
    indented.print(indented.level)
    with indented:
        indented.print(indented.level)
        with indented:
            indented.print('Hallo', indented.level)
            with indented:
                indented.print(indented.level)
            indented.print('and back one level', indented.level)


if __name__ == '__main__':
    main()

输出:

0
  1
    Hallo 2
      3
    and back one level 2

To solve the ”real” problem that lead to your question you could implement a contextmanager which keeps track of the indention level and make the with block structure in the code correspond to the indentation levels of the output. This way the code indentation still reflects the output indentation without coupling both too much. It is still possible to refactor the code into different functions and have other indentations based on code structure not messing with the output indentation.

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function


class IndentedPrinter(object):

    def __init__(self, level=0, indent_with='  '):
        self.level = level
        self.indent_with = indent_with

    def __enter__(self):
        self.level += 1
        return self

    def __exit__(self, *_args):
        self.level -= 1

    def print(self, arg='', *args, **kwargs):
        print(self.indent_with * self.level + str(arg), *args, **kwargs)


def main():
    indented = IndentedPrinter()
    indented.print(indented.level)
    with indented:
        indented.print(indented.level)
        with indented:
            indented.print('Hallo', indented.level)
            with indented:
                indented.print(indented.level)
            indented.print('and back one level', indented.level)


if __name__ == '__main__':
    main()

Output:

0
  1
    Hallo 2
      3
    and back one level 2

回答 4

>>> import inspect
>>> help(inspect.indentsize)
Help on function indentsize in module inspect:

indentsize(line)
    Return the indent size, in spaces, at the start of a line of text.
>>> import inspect
>>> help(inspect.indentsize)
Help on function indentsize in module inspect:

indentsize(line)
    Return the indent size, in spaces, at the start of a line of text.

为什么Python pep-8强烈建议在制表符上使用空格来缩进?

问题:为什么Python pep-8强烈建议在制表符上使用空格来缩进?

我在Stack Overflow和PEP 8上看到,建议是仅将空格用于Python程序中的缩进。我能理解保持一致的缩进的必要性,我已经感到痛苦。

是否存在首选空间的根本原因?我本以为使用选项卡要容易得多。

I see on Stack Overflow and PEP 8 that the recommendation is to use spaces only for indentation in Python programs. I can understand the need for consistent indentation and I have felt that pain.

Is there an underlying reason for spaces to be preferred? I would have thought that tabs were far easier to work with.


回答 0

答案是在PEP中给出的[ed:此段落已于2013年编辑]。我引用:

缩进Python 的最流行方法是仅使用空格。

您还需要其他哪些根本原因?

坦率地说:如第一段所述,还要考虑PEP的范围:

本文档给出了Python代码的编码约定,该Python代码包含主Python发行版中的标准库。

目的是使正式python发行版本中的所有代码都保持一致的格式(我希望我们可以同意这是普遍适用的Good Thing™)。

由于对于单个程序员而言,空格和制表符之间的决定是a)确实是个问题,并且b)可以通过技术手段(编辑器,转换脚本等)轻松解决,因此有一种明确的方法可以结束所有讨论:选择一个。

Guido是一个可供选择的人。他甚至不必给出理由,但他仍然通过引用经验数据来做到这一点。

对于所有其他目的,您可以将此PEP作为建议,也可以忽略它-您的选择,团队的选择或团队的领导者。

但是,如果我能给您一个建议:请不要混合使用它们;-) [ed:不再使用制表符和空格混合。]

The answer was given right there in the PEP [ed: this passage has been edited out in 2013]. I quote:

The most popular way of indenting Python is with spaces only.

What other underlying reason do you need?

To put it less bluntly: Consider also the scope of the PEP as stated in the very first paragraph:

This document gives coding conventions for the Python code comprising the standard library in the main Python distribution.

The intention is to make all code that goes in the official python distribution consistently formatted (I hope we can agree that this is universally a Good Thing™).

Since the decision between spaces and tabs for an individual programmer is a) really a matter of taste and b) easily dealt with by technical means (editors, conversion scripts, etc.), there is a clear way to end all discussion: choose one.

Guido was the one to choose. He didn’t even have to give a reason, but he still did by referring to empirical data.

For all other purposes you can either take this PEP as a recommendation, or you can ignore it — your choice, or your team’s, or your team leaders.

But if I may give you one advice: don’t mix’em ;-) [ed: Mixing tabs and spaces is no longer an option.]


回答 1

好吧,似乎每个人都强烈偏爱空间。我专门使用制表符。我很清楚为什么。

标签实际上是一个很酷的发明,来到空格。它使您可以缩进而无需数百万次按空格或使用伪造的制表符(产生空格)。

我真的不明白为什么每个人都在区别使用制表符。这很像老年人歧视年轻人,因为他们选择了更新的更有效的技术,并且抱怨脉冲拨号在每部电话都有效不仅在这些花哨的新。“音调拨号并非在所有电话上都有效,这就是为什么它是错误的”。

您的编辑器无法正确处理标签?好吧,请一位现代编辑。也许该死的时代,我们现在处于21世纪,而编辑器是高科技复杂软件的时代已经过去很久了。现在,我们有无数的编辑者可供选择,所有这些人都支持选项卡。另外,您可以定义制表符应该有多少,而空格则无法做到。看不到标签?那是什么意思呢?好吧,您也看不到空格!

我可以这么大胆地建议找一个更好的编辑器吗?这些高科技产品之一,已经在10年前发布了,它们显示了看不见的字符?(嘲讽)

使用空格会导致更多的删除和格式化工作。这就是为什么(以及所有其他知道这一点并同意我的人)使用Python的选项卡的原因。

制表符和空格的混合是不行的,对此也不存在任何参数。那是一团糟,永远无法正常工作。

Well well, seems like everybody is strongly biased towards spaces. I use tabs exclusively. I know very well why.

Tabs are actually a cool invention, that came after spaces. It allows you to indent without pushing space millions of times or using a fake tab (that produces spaces).

I really don’t get why everybody is discriminating the use of tabs. It is very much like old people discriminating younger people for choosing a newer more efficient technology and complaining that pulse dialing works on every phone, not just on these fancy new ones. “Tone dialing doesn’t work on every phone, that’s why it is wrong”.

Your editor cannot handle tabs properly? Well, get a modern editor. Might be darn time, we are now in the 21st century and the time when an editor was a high tech complicated piece of software is long past. We have now tons and tons of editors to choose from, all of them that support tabs just fine. Also, you can define how much a tab should be, a thing that you cannot do with spaces. Cannot see tabs? What is that for an argument? Well, you cannot see spaces neither!

May I be so bold to suggest to get a better editor? One of these high tech ones, that were released some 10 years ago already, that display invisible characters? (sarcasm off)

Using spaces causes a lot more deleting and formatting work. That is why (and all other people that know this and agree with me) use tabs for Python.

Mixing tabs and spaces is a no-no and no argument about that. That is a mess and can never work.


回答 2

我个人不同意制表符上的空格。对我而言,制表符是文档布局的字符/机制,而在代码情况下,空格用于表示命令之间的内容或命令之间的轮廓。

我必须同意吉姆(Jim)的评论,即制表符并不是真正的问题,这是人们以及他们想如何混合使用制表符和空格。

就是说,为了惯例起见,我强迫自己使用空格。我重视一致性而不是个人喜好。

I personally don’t agree with spaces over tabs. To me, tabs are a document layout character/mechanism while spaces are for content or delineation between commands in the case of code.

I have to agree with Jim’s comments that tabs aren’t really the issue, it is people and how they want to mix tabs and spaces.

That said, I’ve forced myself to use spaces for the sake of convention. I value consistency over personal preference.


回答 3

空格的原因是选项卡是可选的。在标点符号中,空格是实际的最低公分母。

每个体面的文本编辑器都有一个“用空格替换选项卡”,许多人都使用它。但不总是。

尽管某些文本编辑器可能会用制表符代替一排空格,但这确实很少见。

底线。空格绝对不会出错。你可能会出差错的标签。因此,请勿使用制表符,以减少出错的风险。

The reason for spaces is that tabs are optional. Spaces are the actual lowest-common denominator in punctuation.

Every decent text editor has a “replace tabs with spaces” and many people use this. But not always.

While some text editors might replace a run of spaces with a tab, this is really rare.

Bottom Line. You can’t go wrong with spaces. You might go wrong with tabs. So don’t use tabs and reduce the risk of mistakes.


回答 4

制表符的问题在于它们是不可见的,人们永远无法就制表符的宽度达成共识。当您混合使用制表符和空格,并且将制表符设置为除Python之外的其他选项(每8个空格使用制表符)时,您将看到的代码布局与Python看到的布局不同。并且由于布局确定了块,因此您将看到不同的逻辑。它导致细微的错误。

如果您坚持要违反PEP 8并使用制表符-或更糟糕的是,混用制表符和空格-至少总是将python与’-tt’参数一起运行,这会使缩进不一致(有时是制表符,有时会为相同的缩进使用空格级别)的错误。另外,如果可能,将编辑器设置为以不同方式显示选项卡。但实际上,最好的方法是不要使用制表符。

The problem with tabs is that they are invisible, and people can never agree on the width of tabs. When you mix tabs and spaces, and you set tabstops at something other than Python (which uses tabstops every 8 spaces) you will be seeing the code in a different layout than Python sees it. And because the layout determines blocks, you will be seeing different logic. It leads to subtle bugs.

If you insist on defying PEP 8 and using tabs — or worse, mixing tabs and spaces — at least always run python with the ‘-tt’ argument, which makes inconsistent indentation (sometimes a tab, sometimes a space for the same indentation level) an error. Also, if possible, set your editor to display tabs differently. But really, the best approach is not to use tabs, period.


回答 5

混合制表符和空格时会出现缩进的主要问题。显然,这并不能告诉您应该选择哪一个,但这是推荐一个很好的理由,即使您是通过掷硬币来挑选它的。

但是,恕我直言,有一些较小的理由偏爱制表符而不是制表符:

  • 不同的工具。有时代码会显示在程序员的编辑器之外。例如。发布到新闻组或论坛。在这里,空格通常比制表符更好-到处都会弄乱空格,制表符也是如此,但反之则不然。

  • 程序员对源代码的看法有所不同。这是非常主观的-它要么是制表符的主要优点,要么是根据您所站在的那一侧来避免使用它们的原因。从好的方面来说,开发人员可以使用首选缩进方式查看源代码,因此更喜欢2空间缩进的开发人员可以与8空间开发人员在同一源代码上一起工作,并且仍然可以随意查看它们。不利的一面是,这给人带来了影响-有些人喜欢8空格,因为它提供了非常明显的嵌套嵌套的非常明显的反馈-他们可能会看到2-indenter检入的代码不断地包裹在编辑器中。让每个开发人员以相同的方式查看代码将导致行长度的一致性更高,以及其他一些问题。

  • 续行缩进。有时您希望缩进一行以指示它是从上一行开始的。例如。

    def foo():
        x = some_function_with_lots_of_args(foo, bar, baz,
                                            xyzzy, blah)

    如果使用制表符,则无法在不混用空格和制表符的情况下,针对在编辑器中使用不同制表符的人们进行调整。这有效地扼杀了上述好处。

但是,显然,这是一个深切的宗教问题,编程受到困扰。最重要的问题是我们应该选择一个-即使那不是您喜欢的那个。有时,我认为显着缩进的最大优点是至少我们没有幸免放置牙套。

同样值得一读的是杰米·扎温斯基(Jamie Zawinski )的这篇文章。

The main problems with indentation occur when you mix tabs and spaces. Obviously this doesn’t tell you which you should choose, but it is a good reason to to recommend one, even if you pick it by flipping a coin.

However, IMHO there are a few minor reasons to favour spaces over tabs:

  • Different tools. Sometimes code gets displayed outside of a programmer’s editor. Eg. posted to a newsgroup or forum. Spaces generally do better than tabs here – everywhere spaces would get mangled, tabs do as well, but not vice-versa.

  • Programmers see the source differently. This is deeply subjective – its either the main benefit of tabs, or a reason to avoid them depending on which side you’re on. On the plus side, developers can view the source with their preferred indentation, so a developer preferring 2-space indent can work with an 8-space developer on the same source and still see it as they like. The downside is that there are repercussions to this – some people like 8-space because it gives very visible feedback that they’re too deeply nested – they may see code checked in by the 2-indenter constantly wrapping in their editor. Having every developer see the code the same way leads to more consistency wrt line lengths, and other matters too.

  • Continued line indentation. Sometimes you want to indent a line to indicate it is carried from the previous one. eg.

    def foo():
        x = some_function_with_lots_of_args(foo, bar, baz,
                                            xyzzy, blah)
    

    If using tabs, theres no way to align this for people using different tabstops in their editor without mixing spaces and tabs. This effectively kills the above benefit.

Obviously though, this is a deeply religious issue, which programming is plagued with. The most important issue is that we should choose one – even if thats not the one you favour. Sometimes I think that the biggest advantage of significant indentation is that at least we’re spared brace placement flamewars.

Also worth reading is this article by Jamie Zawinski on the issue.


回答 6

请注意,使用制表符会混淆PEP 8的另一方面:

限制所有行最多79个字符。

假设,假设您使用2的制表符宽度,而我使用8的制表符宽度。编写所有代码,以使最长行达到79个字符,然后我开始处理文件。现在,我有一些难以阅读的代码,因为(如PEP所述):

大多数工具中的默认包装会破坏代码的视觉结构

如果我们都使用4个空格,那就总是一样。编辑器可以支持80个字符的宽度的任何人都可以轻松阅读代码。注意:80个字符的限制本身就是一场神圣的战争,因此,我们不要从这里开始。

任何不精简的编辑器都应该有一个使用空格的选项,就好像它们是制表符一样(插入和删除),因此实际上不应是有效的参数。

Note that the use of tabs confuses another aspect of PEP 8:

Limit all lines to a maximum of 79 characters.

Let’s say, hypothetically, that you use a tab width of 2 and I use a tab width of 8. You write all your code so your longest lines reach 79 characters, then I start to work on your file. Now I’ve got hard-to-read code because (as the PEP states):

The default wrapping in most tools disrupts the visual structure of the code

If we all use 4 spaces, it’s ALWAYS the same. Anyone whose editor can support an 80 character width can comfortably read the code. Note: The 80 character limit is a holy war in and of itself, so let’s not start that here.

Any non-sucky editor should have an option to use spaces as if they were tabs (both inserting and deleting), so that really shouldn’t be a valid argument.


回答 7

问题的答案是:PEP-8希望提出建议,并决定由于空格更为流行,因此强烈建议在制表符上推荐空格。


关于PEP-8的注意事项

PEP-8说:“每个缩进级别使用4个空格。”
很明显,这是标准建议。

“对于不想弄乱的真正旧代码,您可以继续使用8位制表符。”
很明显,在某些情况下可以使用选项卡。

“切勿混用制表符和空格。”
明确禁止混用-我认为我们都对此表示同意。Python可以检测到这一点,并且经常使人窒息。使用-tt参数使它成为显式错误。

‘缩进Python的最流行方法是仅使用空格。第二流行的方式是仅使用标签。
这清楚地表明两者都被使用。只是要非常清楚:您仍不应在同一文件中混用空格和制表符。

“对于新项目,强烈建议在选项卡上仅使用空格。”
这是一个明确的建议,是一个强有力的建议,但不是禁止使用制表符。


在PEP-8中,我找不到自己的问题的好答案。我使用的标签是我以前在其他语言中使用过的标签。Python接受使用制表符专用的源代码。对我来说足够了。

我以为我会尝试使用空间。在编辑器中,我将文件类型配置为仅使用空格,因此如果按Tab键,它将插入4个空格。如果按Tab键太多次,则必须删除空格! 啊! 删除次数是标签页的四倍!我的编辑器无法告诉我我为缩进使用了4个空格(尽管AN编辑器可以做到这一点),并且显然坚持每次删除一个空格。

难道不建议Python在读取缩进时将制表符视为n个空格吗?如果我们可以同意每个缩进4个空格和每个制表符4个空格并允许Python接受,则不会有问题。
我们应该找到双赢的解决方案。

The answer to the question is: PEP-8 wants to make a recommendation and has decided that since spaces are more popular it will strongly recommend spaces over tabs.


Notes on PEP-8

PEP-8 says ‘Use 4 spaces per indentation level.’
Its clear that this is the standard recommendation.

‘For really old code that you don’t want to mess up, you can continue to use 8-space tabs.’
Its clear that there are SOME circumstances when tabs can be used.

‘Never mix tabs and spaces.’
This is a clear prohibition of mixing – I think we all agree on this. Python can detect this and often chokes. Using the -tt argument makes this an explicit error.

‘The most popular way of indenting Python is with spaces only. The second-most popular way is with tabs only.’
This clearly states that both are used. Just to be ultra-clear: You should still never mix spaces and tabs in same file.

‘For new projects, spaces-only are strongly recommended over tabs.’
This is a clear recommendation, and a strong one, but not a prohibition of tabs.


I can’t find a good answer to my own question in PEP-8. I use tabs, which I have used historically in other languages. Python accepts source with exclusive use of tabs. That’s good enough for me.

I thought I would have a go at working with spaces. In my editor, I configured a file type to use spaces exclusively and so it inserts 4 spaces if I press tab. If I press tab too many times, I have to delete the spaces! Arrgh! Four times as many deletes as tabs! My editor can’t tell that I’m using 4 spaces for indents (although AN editor might be able to do this) and obviously insists on deleting the spaces one at a time.

Couldn’t Python be told to consider tabs to be n spaces when its reading indentations? If we could agree on 4 spaces per indentation and 4 spaces per tab and allow Python to accept this, then there would be no problems.
We should find win-win solutions to problems.


回答 8

我一直在代码中使用制表符。就是说,我最近找到了使用空格的理由:在诺基亚N900互联网平板电脑上进行开发时,我现在有了一个没有Tab键的键盘。这迫使我要么复制和粘贴选项卡,要么用空格重写我的代码。我在其他手机上也遇到了同样的问题。当然,这不是Python的标准用法,但需要牢记。

I’ve always used tabs in my code. That said, I’ve recently found a reason to use spaces: When developing on my Nokia N900 internet tablet, I now had a keyboard without a tab key. This forced me to either copy and paste tabs or re-write my code with spaces. I’ve run into the same problem with other phones. Granted, this is not a standard use of Python, but something to keep in mind.


回答 9

JWZ说得最好

当[人们]正在阅读代码时,当他们写完新代码时,他们会在打开新的作用域(或sexpr或其他东西)时关心代码倾向于缩进多少屏幕列…

…我的观点是,解决技术问题的最佳方法是强制要求ASCII#9 TAB字符永远不会出现在磁盘文件中:对编辑器进行编程,以将TAB扩展到适当数量的空格,然后再将行写入磁盘。 ..

…这假设您从未在制表符真正重要的地方使用过制表符,例如在字符串或字符常量中,但是我从不这样做:当重要的是制表符时,我总是使用’​​\ t’代替。

JWZ says it best:

When [people are] reading code, and when they’re done writing new code, they care about how many screen columns by which the code tends to indent when a new scope (or sexpr, or whatever) opens…

…My opinion is that the best way to solve the technical issues is to mandate that the ASCII #9 TAB character never appear in disk files: program your editor to expand TABs to an appropriate number of spaces before writing the lines to disk…

…This assumes that you never use tabs in places where they are actually significant, like in string or character constants, but I never do that: when it matters that it is a tab, I always use ‘\t’ instead.


回答 10

由于python依靠缩进来识别程序结构,因此需要一种明确的方法来识别标识。这就是选择空格或制表符的原因。

但是,python也有一个很强的哲学,即只有一种方法可以做事,因此应该正式建议一种缩进方法。

空格和制表符都给编辑人员处理缩进带来了独特的挑战。选项卡本身的处理在不同的编辑器甚至用户设置之间都不统一。由于空格是不可配置的,因此它们提供了更合乎逻辑的选择,因为它们可以保证结果在各个地方看起来都一样。

Since python relies on indentation in order to recognize program structure, a clear way to identify identation is required. This is the reason to pick either spaces or tabs.

However, python also has a strong philosophy of only having one way to do things, therefore there should be an official recommendation for one way to do indentation.

Both spaces and tabs pose unique challenges for an editor to handle as indentation. The handling of tabs themselves is not uniform across editors or even user settings. Since spaces are not configurable, they pose the more logical choice as they guarantee that the outcome will look everywhere the same.


回答 11

关于制表符,我能说出的最重要的好处是,许多程序员和项目使用一组列的源代码,并且如果有人提交了一个更改,将他们的tabstop设置为2个空格,而项目使用了4个空格作为制表符,对于其他人的编辑器窗口,长行将太长。我同意制表符更易于使用,但我认为空格更易于协作,这在像Python这样的大型开源项目中很重要。

The most significant advantage I can tell of spaces over tabs is that a lot of programmers and projects use a set number of columns for the source code, and if someone commits a change with their tabstop set to 2 spaces and the project uses 4 spaces as the tabstop the long lines are going to be too long for other people’s editor window. I agree that tabs are easier to work with but I think spaces are easier for collaboration, which is important on a large open source project like Python.


回答 12

你可以吃蛋糕吃。设置编辑器以将选项卡自动展开为空格。

:set expandtab在Vim中。)

You can have your cake and eat it to. Set your editor to expand tabs into spaces automatically.

(That would be :set expandtab in Vim.)


回答 13

我的猜测是,大多数linux文本编辑器默认情况下都会使默认值看起来大得离谱。我想不出其他理由来在制表符上使用空格。

My guess is that most the linux text editors make defaults look ridiculously large by default. I can’t think of any other good reason to use spaces over tabs.


回答 14

除了已经命名的所有其他原因(一致性,不要混用空格和制表符等)之外,我相信还有其他一些理由可以说明这4个空格约定。这些仅适用于Python(可能还有缩进有意义的其他语言)。根据个人喜好,其他语言的选项卡可能更好。

  1. 如果编辑器没有显示选项卡(根据配置的不同,发生的次数很多),那么另一位作者可能会假设您的代码使用4个空格,几乎所有可公开获得的Python代码都会使用4个空格。如果同一编辑器的制表符宽度为4,则可能会发生令人讨厌的事情-至少,那个穷人会因为遵循惯例而很容易避免的缩进问题而浪费时间。因此,对我而言,首要原因是避免具有一致性的错误。

  2. 回顾制表符或空格中哪个更好的问题,应该问一下制表符的优点是什么;我见过很多赞美标签的帖子,但很少有令人信服的论点。emacs,vi(m),kate等优秀的编辑器会根据您代码的语义进行适当的缩进-即使没有制表符也是如此;可以轻松地将相同的编辑器配置为在退格键等上缩进。

  3. 在决定代码的外观/布局的自由方面,有些人有很强的偏好。其他人则重视这种自由的一致性。Python通过指示将缩进用于块等来极大地降低了这种自由度。这可能被视为错误或功能,但选择Python会带来一些麻烦。就个人而言,我喜欢这种一致性-在开始为新项目进行编码时,至少布局与我惯用的布局非常接近,因此相当容易阅读。几乎总是。

  4. 使用空格进行缩进允许“布局技巧”,这些技巧可能有助于理解代码。PEP8中列出了其中一些示例;例如。

    foo = long_function_name(var_one, var_two,
                             var_three, var_four)
    
    # the same for lists
    a_long_list = [1,
                   2,
                   # ...
                   79]
    
    # or dictionaries
    a_dict = {"a_key": "a_value",
              "another_key": "another_value"}

    当然,以上内容也可以写得很好

    foo = long_function_name(
        var_one, var_two,
        var_three, var_four)
    
    # the same for lists
    a_long_list = [
        1,
        2,
        # ...
        79]
    
    # or dictionaries
    a_dict = {
        "a_key": "a_value",
        "another_key": "another_value"}

    但是,后者占用了更多的代码行,并且有时认为更少的行会更好(b / c您可以在一个屏幕上得到更多)。但是,如果您喜欢对齐,则从某种意义上说,空格(最好由一个好的编辑器协助)在Python中为您提供了比制表符更多的自由度。[好吧,我猜有些编辑器允许您使用制表符执行相同的操作;)-但如果有空格,所有的编辑器都可以执行…]

  5. 回到其他人都提出的相同论点-PEP 8指示(好的,强烈建议)空格。当然,如果来到仅使用选项卡的项目,则别无选择。但是由于建立了PEP 8约定,几乎所有Python程序员都习惯了这种样式。这使得在大多数程序员都能接受的风格上达成共识变得容易得多,否则让个人对风格达成共识可能很难。

  6. 通常,帮助执行样式的工具无需费力即可了解PEP 8。这不是一个很好的理由,但是开箱即用就可以了。

Besides all the other reasons already named (consistency, never mixing spaces and tabs etc) I believe there are a few more reasons for the 4 spaces convention to note. These only apply to Python (and maybe other languages where indentation has meaning). Tabs may be nicer in other languages, depending on individual preferences.

  1. If an editor doesn’t show tabs (which happens, depending on the configuration, in quite a few), another author might assume that your code uses 4 spaces, b/c almost all of the Python code being publicly available does; if that same editor happens to have a tab width of 4, nasty things may happen – at least, that poor person will lose time over an indentation issue that would have been very easy to avoid by sticking to the convention. So for me, the number one reason is to avoid bugs with consistency.

  2. Reframing the question of which is better, tabs or spaces, one should ask which the advantages of tabs are; I’ve seen plenty posts praising tabs, but few compelling arguments for them; good editors like emacs, vi(m), kate, … do proper indentation depending on the semantics of your code – even without tabs; the same editors can easily be configured to unindent on backspace etc.

  3. Some people have very strong preferences when it comes to their freedom in deciding the look/ layout of code; others value consistency over this freedom. Python drastically reduces this freedom by dictating that indentation is used for blocks etc. This may be seen as a bug or a feature, but it sort of comes with choosing Python. Personally, I like this consistency – when starting to code on a new project, at least the layout is close to what I’m used to, so it’s fairly easy to read. Almost always.

  4. Using spaces for indentation allows “layout tricks” that may facilitate to comprehend code; some examples of these are listed in PEP8; eg.

    foo = long_function_name(var_one, var_two,
                             var_three, var_four)
    
    # the same for lists
    a_long_list = [1,
                   2,
                   # ...
                   79]
    
    # or dictionaries
    a_dict = {"a_key": "a_value",
              "another_key": "another_value"}
    

    Of course, the above can also be written nicely as

    foo = long_function_name(
        var_one, var_two,
        var_three, var_four)
    
    # the same for lists
    a_long_list = [
        1,
        2,
        # ...
        79]
    
    # or dictionaries
    a_dict = {
        "a_key": "a_value",
        "another_key": "another_value"}
    

    However, the latter takes more lines of code and less lines are sometimes argued to be better (b/c you get more on a single screen). But if you like alignment, spaces (preferably assisted by a good editor) give you, in a sense, more freedom in Python than tabs. [Well, I guess some editors allow you to do the same w/ tabs ;) – but with spaces, all of them do…]

  5. Coming back to the same argument that everybody else makes – PEP 8 dictates (ok, strongly recommends) spaces. If coming to a project that uses tabs only, of course, you have little choice. But because of the establishment of the PEP 8 conventions, almost all Python programmers are used to this style. This makes it sooooo much easier to find a consensus on a style that is accepted by most programmers… and having individuals agree on style might be very hard otherwise.

  6. Tools that help enforcing style are usually aware of PEP 8 without extra effort. That’s not a great reason, but it’s just nice to have things work ~out of the box.


回答 15

制表符的普遍问题是它们在不同环境中的表示方式可能不同。
在给定的编辑器中,选项卡可能是8个空格,也可能是2个空格。
在某些编辑器中,您可以控制它,而在其他编辑器中,则不能。

制表符的另一个问题是它们在打印输出中的表示方式。我相信大多数打印机会将制表符解释为8个空格。

毫无疑问,有了空格。一切都会按照作者的意图排列。

The universal problem with tabs is that they can be represented differently in different environment.
In a given editor, a tab might be 8 spaces or it might be 2.
In some editors, you can control this, while in others you can’t.

Another issue with tabs is how they are represented in printed output. I believe most printers interpret a tab as 8 spaces.

With spaces, there is no doubt. Everything will line up as the author intended.


回答 16

关于Jim和Thomas Wouters之间的讨论

问题是…因为制表符和空格的宽度都可以变化-并且由于程序员不能在这两个宽度上达成共识-为什么制表符要怪罪。

我同意吉姆的观点-制表符本身并不邪恶。但有个问题…

使用空格,我可以控制“我自己的代码” 世界上每个编辑器中外观。如果我使用4个空格-则无论您在哪个编辑器中打开我的代码,它与左边距的距离都是相同的。使用标签时,我受制于编辑器的标签宽度设置-甚至对于我自己的代码也是如此。我不喜欢那样

因此,即使空格不能保证一致性也确实如此-它们至少使您可以更好地控制OWN代码的外观-制表符无法做到。

我认为,这并不是使程序员更容易实现(并强加)空格的方法,而是程序员编写代码的一致性,而是显示代码的编辑器的一致性。

On the discussion between Jim and Thomas Wouters in the comments.

The issue was… since the width of tabs and spaces both can vary — and since programmers can’t agree on either width — why is it that tabs bear the blame.

I agree with Jim on that — tabs are NOT evil in and of themselves. But there is a problem…

With spaces I can control how “MY OWN CODE” looks in EVERY editor in the world. If I use 4 spaces — then no matter what editor you open my code in, it will have the same distance from the left margin. With tabs I am at the mercy of the tab-width setting for the editor — even for MY OWN CODE. And I don’t like that.

So while it is true that even spaces can’t guarantee consistency — they at least afford you more control over the look of your OWN code everywhere — something that tabs can’t.

I think it’s NOT the consistency in the programmers writing the code — but the consistency in editors showing that code — that spaces make easier to achieve (and impose).


在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.


IndentationError:unindent与任何外部缩进级别都不匹配

问题:IndentationError:unindent与任何外部缩进级别都不匹配

当我编译下面的Python代码时,我得到

IndentationError:unindent与任何外部缩进级别都不匹配


import sys

def Factorial(n): # Return factorial
    result = 1
    for i in range (1,n):
        result = result * i
    print "factorial is ",result
    return result

为什么?

When I compile the Python code below, I get

IndentationError: unindent does not match any outer indentation level


import sys

def Factorial(n): # Return factorial
    result = 1
    for i in range (1,n):
        result = result * i
    print "factorial is ",result
    return result

Why?


回答 0

其他海报可能是正确的…选项卡中可能混有空格。尝试执行搜索和替换操作,以将所有标签替换为几个空格。

尝试这个:

import sys

def Factorial(n): # return factorial
    result = 1
    for i in range (1,n):
        result = result * i
    print "factorial is ",result
    return result

print Factorial(10)

Other posters are probably correct…there might be spaces mixed in with your tabs. Try doing a search & replace to replace all tabs with a few spaces.

Try this:

import sys

def Factorial(n): # return factorial
    result = 1
    for i in range (1,n):
        result = result * i
    print "factorial is ",result
    return result

print Factorial(10)

回答 1

重要说明空格是首选方法 -请参阅PEP008 缩进制表符或空格?。(感谢@Siha。)

对于Sublime Text用户:

设置Sublime Text为使用制表符进行缩进: View-> Indentation->Convert Indentation to Tabs

Indent Using Spaces还要取消选中上面相同子菜单中的选项。这将立即解决此问题。

IMPORTANT: Spaces are the preferred method – see PEP008 Indentation and Tabs or Spaces?. (Thanks to @Siha for this.)

For Sublime Text users:

Set Sublime Text to use tabs for indentation: View –> Indentation –> Convert Indentation to Tabs

Uncheck the Indent Using Spaces option as well in the same sub-menu above. This will immediately resolve this issue.


回答 2

要轻松检查制表符/空格的问题,您可以执行以下操作:

python -m tabnanny yourfile.py

或者您当然可以正确设置编辑器:-)

To easily check for problems with tabs/spaces you can actually do this:

python -m tabnanny yourfile.py

or you can just set up your editor correctly of course :-)


回答 3

您确定不在缩进空格中混用制表符和空格吗?(这将导致该错误。)

请注意,建议您不要在Python代码中使用制表符。请参阅样式指南。您应该配置Notepad ++以便为选项卡插入空格。

Are you sure you are not mixing tabs and spaces in your indentation white space? (That will cause that error.)

Note, it is recommended that you don’t use tabs in Python code. See the style guide. You should configure Notepad++ to insert spaces for tabs.


回答 4

每当遇到此错误时,都是因为我以某种方式混淆了编辑器中的制表符和空格。

Whenever I’ve encountered this error, it’s because I’ve somehow mixed up tabs and spaces in my editor.


回答 5

如果使用Python的IDLE编辑器,则可以按照类似的错误消息之一进行操作:

1)全选,例如Ctrl+A

2)转到格式->取消制表区域

3)仔细检查您的缩进是否仍然正确,保存并重新运行您的程序。

我正在使用Python 2.5.4

If you use Python’s IDLE editor you can do as it suggests in one of similar error messages:

1) select all, e.g. Ctrl + A

2) Go to Format -> Untabify Region

3) Double check your indenting is still correct, save and rerun your program.

I’m using Python 2.5.4


回答 6

如果您使用的是Vim,请按Escape键,然后输入

gg = G

这会自动缩进所有内容,并清除您抛出的所有空格。

If you are using Vim, hit escape and then type

gg=G

This auto indents everything and will clear up any spaces you have thrown in.


回答 7

这行:result = result * i应该缩进(这是for循环的主体)。

或者-您混合使用空格和制表符

The line: result = result * i should be indented (it is the body of the for-loop).

Or – you have mixed space and tab characters


回答 8

原子上

Packages > Whitespace > Convert Spaces to Tabs

然后再次检查您的文件缩进:

python -m tabnanny yourFile.py

要么

>python
>>> help("yourFile.py")

On Atom

go to

Packages > Whitespace > Convert Spaces to Tabs

Then check again your file indentation:

python -m tabnanny yourFile.py

or

>python
>>> help("yourFile.py")

回答 9

看起来是一个缩进问题。你不必匹配在Python大括号,但你必须匹配缩进层次。

防止空格/制表符问题的最佳方法是在文本编辑器中显示不可见的字符。这将为您提供预防和/或解决与缩进相关的错误的快速方法。

同样,注入复制粘贴的代码是此类问题的常见来源。

Looks to be an indentation problem. You don’t have to match curly brackets in Python but you do have to match indentation levels.

The best way to prevent space/tab problems is to display invisible characters within your text editor. This will give you a quick way to prevent and/or resolve indentation-related errors.

Also, injecting copy-pasted code is a common source for this type of problem.


回答 10

如果使用notepad ++,请使用扩展搜索模式“替换”以找到\ t并用四个空格替换。

If you use notepad++, do a “replace” with extended search mode to find \t and replace with four spaces.


回答 11

对于Atom用户,Packages ->whitspace -> remove trailing whitespaces 这对我有用

for Atom Users, Packages ->whitspace -> remove trailing whitespaces this worked for me


回答 12

只是一个补充。我在Notepad ++中的两个缩进都有类似的问题。

  1. 无exceptions的缩进
  2. 外压痕等级

    转到—->搜索选项卡—->点击替换 —->选中单选按钮扩展到下面—>现在用四个空格替换\ t

    转到—->搜索选项卡—->点击替换 —->按下单选按钮扩展到下面—>现在将\ n替换为空

Just a addition. I had a similar problem with the both indentations in Notepad++.

  1. Unexcepted indentation
  2. Outer Indentation Level

    Go to —-> Search tab —-> tap on replace —-> hit the radio button Extended below —> Now replace \t with four spaces

    Go to —-> Search tab —-> tap on replace —-> hit the radio button Extended below —> Now replace \n with nothing


回答 13

我使用的是Jupyter笔记本,尝试了几乎所有上述解决方案(以适应我的情况)为无效。然后,我一行一行地删除了每一行的所有空格,并用tab代替了。那解决了问题。

I was using Jupyter notebook and tried almost all of the above solutions (adapting to my scenario) to no use. I then went line by line, deleted all spaces for each line and replaced with tab. That solved the issue.


回答 14

对于Spyder用户,请 转至源>修复缩进以立即解决问题

For Spyder users goto Source > Fix Indentation to fix the issue immediately


回答 15

可能是因为其上方的函数缩进方式不同。即

class a:
    def blah:
      print("Hello world")
    def blah1:
      print("Hello world")

It could be because the function above it is not indented the same way. i.e.

class a:
    def blah:
      print("Hello world")
    def blah1:
      print("Hello world")

回答 16

昨天我遇到了同样的问题,这是缩进错误,正在使用崇高的文本编辑器。花了我几个小时的时间来修复它,最后我最终将代码复制到VI文本编辑器中,并且运行良好。ps python对空格太敏感,请确保不要混合使用空格和制表符。

I had the same issue yesterday, it was indentation error, was using sublime text editor. took my hours trying to fix it and at the end I ended up copying the code into VI text editor and it just worked fine. ps python is too whitespace sensitive, make sure not to mix space and tab.


回答 17

因为我意识到没有特定的答案spyder,所以我将添加一个答案:基本上,仔细查看您的if声明并确保全部ifelifelse具有相同的间距,即它们在开始时位于同一行,如下所示:

def your_choice(answer):
    if answer>5:
        print("You're overaged")
    elif answer<=5 and answer>1: 
            print("Welcome to the toddler's club!")
    else:
            print("No worries mate!")

Since I realize there’s no answer specific to spyder,I’ll add one: Basically, carefully look at your if statement and make sure all if, elif and else have the same spacing that is they’re in the same line at the start like so:

def your_choice(answer):
    if answer>5:
        print("You're overaged")
    elif answer<=5 and answer>1: 
            print("Welcome to the toddler's club!")
    else:
            print("No worries mate!")

回答 18

我定义了一个函数,但除了函数注释外,它没有任何内容

def foo(bar):
    # Some awesome temporary comment.
    # But there is actually nothing in the function!
    # D'Oh!

大喊:

  File "foobar.py", line 69

                                ^
IndentationError: expected an indented block

(请注意,^标记指向的行为空)

多种解决方案:

1:仅将功能注释掉

2:添加功能注释

def foo(bar):
    '' Some awesome comment. This comment could be just one space.''

3:添加不执行任何操作的行

def foo(bar):
    0

在任何情况下,请务必使其明显的 ,为什么它是一个空的功能-为自己,或您的同事将使用代码

I had a function defined, but it did not had any content apart from its function comments…

def foo(bar):
    # Some awesome temporary comment.
    # But there is actually nothing in the function!
    # D'Oh!

It yelled :

  File "foobar.py", line 69

                                ^
IndentationError: expected an indented block

(note that the line the ^ mark points to is empty)

Multiple solutions:

1: Just comment out the function

2: Add function comment

def foo(bar):
    '' Some awesome comment. This comment could be just one space.''

3: Add line that does nothing

def foo(bar):
    0

In any case, make sure to make it obvious why it is an empty function – for yourself, or for your peers that will use your code


回答 19

首先,只是提醒您有一个逻辑错误,您最好保持result = 1,否则即使在循环运行后,您的输出也将为result = 0。

其次,您可以这样编写:

import sys

def Factorial(n): # Return factorial
  result = 0
  for i in range (1,n):
     result = result * i

  print "factorial is ",result
  return result

留下一行将告诉python shell FOR语句已经结束。如果您有使用python shell的经验,那么您可以理解为什么我们必须行。

Firstly, just to remind you there is a logical error you better keep result=1 or else your output will be result=0 even after the loop runs.

Secondly you can write it like this:

import sys

def Factorial(n): # Return factorial
  result = 0
  for i in range (1,n):
     result = result * i

  print "factorial is ",result
  return result

Leaving a line will tell the python shell that the FOR statements have ended. If you have experience using the python shell then you can understand why we have to leave a line.


回答 20

对于它的价值,我的文档字符串缩进太多,这也引发了相同的错误

class junk: 
     """docstring is indented too much""" 
    def fun(): return   

IndentationError: unindent does not match any outer indentation level

For what its worth, my docstring was indented too much and this also throws the same error

class junk: 
     """docstring is indented too much""" 
    def fun(): return   

IndentationError: unindent does not match any outer indentation level


回答 21

这是因为制表符和空格混在一起。您可以删除所有空格,然后将其替换为制表符。

或者,尝试编写以下代码:

#!/usr/bin/python -tt

在代码的开头。此行解决了制表符和空格之间的所有差异。

This is because there is a mix-up of both tabs and spaces. You can either remove all the spaces and replace them with tabs.

Or, Try writing this:

#!/usr/bin/python -tt

at the beginning of the code. This line resolves any differences between tabs and spaces.


回答 22

就我而言,问题是在Eclipse上配置pydev

in my case, the problem was the configuration of pydev on Eclipse


回答 23

如果使用Komodo编辑器,则可以按照以下类似错误消息之一的建议进行操作:

1)全选,例如Ctrl + A

2)转到代码->取消制表区域

3)仔细检查您的缩进是否仍然正确,保存并重新运行您的程序。

我正在使用Python 3.4.2

If you use Komodo editor you can do as it suggests in one of similar error messages:

1) select all, e.g. Ctrl + A

2) Go to Code -> Untabify Region

3) Double check your indenting is still correct, save and rerun your program.

I’m using Python 3.4.2


回答 24

如果您将Sublime文本用于python开发,则可以使用Anaconda软件包来避免该错误。安装Anaconda后,

  1. 崇高地打开文件
  2. 右键单击开放空间
  3. 选择水蟒
  4. 点击自动格式化
  5. 完成或按CTRL + ALT + R。

If you are using Sublime text for python development,you can avoid the error by using the package Anaconda.After installing Anaconda,

  1. open your file in sublime
  2. right click on the open spaces
  3. choose anaconda
  4. click on autoformat
  5. DONE Or Press CTRL+ALT+R.

回答 25

在具有python插件的intellij中,按Ctrl + Shift + Alt重新格式化文档可解决缩进/制表符/空格问题

In intellij with python plugin, Ctrl + Shift + Alt to reformat the document fixed the indent/tab/spaces problem


回答 26

对于SPYDER用户:我将spyder 3.3.2与python 3.7.1结合使用,并解决了此问题,将缩进设置为使用选项卡,并通过以下步骤单击:

  • 工具。
  • 偏好。
  • 编辑。
  • 高级设置。
  • 缩进字符->制表符。

然后,使用Tab键重置“ unidented”行。

由于某种原因,如果没有此设置,有时会出现幽灵 IndentationError。

For SPYDER users: I’m using spyder 3.3.2 with python 3.7.1 and I solved this, setting indentation to use tabs, with the following steps, click on:

  • Tools.
  • Preferences.
  • Editor.
  • Advanced settings.
  • Indentation characters -> Tabs.

Then I reset the “unidented” line using tab key.

For some reason, without this setting, I got the ghost IndentationError sometimes.


回答 27

例如:

1. def convert_distance(miles):
2.   km = miles * 1.6
3.   return km

在这段代码中,我也遇到了同样的情况。只需删除第2行和第3行的先前缩进空格,然后使用tab或空格即可。切勿同时使用两者。在用python编写代码时,给出适当的缩进。对于Spyder,请转至源>修复缩进。VC代码和崇高文本或任何其他编辑器也是如此。修复缩进。

For example:

1. def convert_distance(miles):
2.   km = miles * 1.6
3.   return km

In this code same situation occurred for me. Just delete the previous indent spaces of line 2 and 3, and then either use tab or space. Never use both. Give proper indentation while writing code in python. For Spyder goto Source > Fix Indentation. Same goes to VC Code and sublime text or any other editor. Fix the indentation.


回答 28

发生这种情况的主要原因是编辑器。尝试将选项卡更改为spaces(4)。最佳的Python友好IDE或编辑器是pycharm,sublime,vim(对于Linux)。
即使我也遇到过同样的问题,后来我发现还有一个编码问题。我建议您也更改您的编辑器。

This happens mainly because of editor .Try changing tabs to spaces(4).the best python friendly IDE or Editors are pycharm ,sublime ,vim for linux.
even i too had encountered the same issue , later i found that there is a encoding issue .i suggest u too change ur editor.