在Perl和C ++中 一个可以通过定义来编写类方法定义 课外的方法,从而避免额外的水平 缩进。
当然那些语言是 自由形式(与Python相反),因此您不必严格为每个添加缩进 嵌套级别,但通常这样做是为了便于阅读。
例如,在C ++中使用以下类定义(方法#1):
class X {
void x_method(int a, int b) {
// implementation details follows here.. Note: extra indentation
}
};
也可以用类外的方法定义编写(方法#2):
class X {
void x_method(int a, int b);
};
void X::x_method(int a, int b) {
// implementation details follows here
}
在Perl中,您可以将第一个版本编写为:
package X {
sub x_method {
my ($a, $b) = @_;
# implementation details follows here
}
}
您可以使用以下样式避免方法定义的额外缩进:
package X;
sub x_method {
my ($a, $b) = @_;
# implementation details follows here
}
package Y; # marks the start of another class
# ...
在这些中 例子我使用了一个小于类的定义 可以在电脑屏幕上查看的线条数量(让我们说吧 少于50行)。对于这样的定义,方法1采用该方法 在课堂上很好。但是,一旦类定义成为 数百行,我更喜欢定义类的方法#2 课外的方法。
但是,我在Python中找不到这种方法。我该怎么做appraoch Python中的#2?
在我看来 你在Python中只有#1的方法:
class X:
def x_method(a, b):
//implementation details follows here
我想有类似的东西(方法#2):
class X:
def x_method(a, b):
# implementation details..
class Y: # marks the start of another class
# ...
当一个类定义中的方法(和行)数量 增加,我认为appraoch#1变得越来越冗长。 然后,我可以看到额外空间(缩进)的唯一目的是 表示方法属于给定的类X. 并且该信息(方法属于给定类)不会 需要扩展和传播越来越多的行作为类 定义增长。将这些信息包含在内是足够的 单行如Perl(使用package语句),或单个前缀单词 在C ++中使用命名空间的结果前缀运算符 名称在其定义的第一行。
我对Python并不熟悉,并且来自其他语言 感觉就像我在冗余空间中窒息(使用方法#1) 对于大类定义,它会分散我的编程注意力 任务。我在这里缺少什么?
额外的缩进也会迫使你打破更多的线条 建议每行限制80个字符。
答案 0 :(得分:2)
你不能在python中使用方法#1,因为除了类之外,可能还有顶级函数定义,因此python将无法确定下面示例中的global_function
是否真的是全局的或属于班级X
:
class X:
def x_method(a, b):
# implementation details..
def global_function(x):
# implementation
class Y: # marks the start of another class
# ...
然而,有一种方法可以减少这样的缩进(但它会使用属于该类的函数污染全局命名空间):
def x_method(self, b):
#implementation
class X:
x_method = x_method
答案 1 :(得分:2)
正如@RomanKonoval暗示的那样,方法只是python中的值,你可以像其他任何值一样修补它们:
def _some_method():
pass
class Foo:
some_method = _some_method
但是,Python不是C ++或Perl。你可能不想这样做!
您应该关注PEP8 style guidelines。几乎可以肯定会阻止这种模式。如果将代码缩进4个空格会使得行太长(PEP8表示你应该包裹在79列),那么你可能会尝试做很多事情(在每一行上,也许在该方法中)。你应该努力寻求小巧,可组合的功能,每一行都很简洁明了。您可以在适当的位置使用行连续,其中行必须溢出。例如:
some_method(that, takes, a_long_list, of_parameters,
that_overflows, onto_the, next_line)
除了风格之外,有一些实际的理由不这样做。首先,如果你使用python的可选输入,我相当肯定mypy不会理解some_method
是Foo
上的实例方法(你可能会看到类似其他静态分析工具的问题,如flake8)。现在我不是说你应该避免某些事情,因为工具不理解它。但是,我的代码最初会让我感到困惑,我怀疑看到它的其他人最初可能会被绊倒。
编辑:我刚才想到的另一点:(再次沿着Python != C++ or Perl
行)Python作为一种语言使设计决定有意义的空白导致更好的代码。事实上,编写良好的Python脚本读起来像英语,并被组织成易于理解的段落式短语。如果你绕过这个只是为了避免一个级别的缩进,那么对于大多数python程序员来说,你的代码更难以阅读。