Python 在类块之外定义对象方法,有什么理由不这样做吗?

Python 在类块之外定义对象方法,有什么理由不这样做吗?,python,django,python-3.x,Python,Django,Python 3.x,下面的内容让我很惊讶,尽管也许它不应该这样做。然而,我从未在其他地方看到过这种情况 def bar_method(self): print( f"in Foo method bar, baz={self.baz}") # and pages more code in the real world class Foo(object): def __init__(self): self.baz = "Quux" bar = bar_method >

下面的内容让我很惊讶,尽管也许它不应该这样做。然而,我从未在其他地方看到过这种情况

def bar_method(self):
    print( f"in Foo method bar, baz={self.baz}")
    # and pages more code in the real world


class Foo(object):
   def __init__(self):
       self.baz = "Quux"
   bar = bar_method

>>> foo = Foo()
>>> foo.bar()
in Foo method bar, baz=Quux
>>>
这源于
def
的定义,它是当前上下文中函数对象对其名称的赋值

就我而言,最大的优点是,我可以将大型方法定义移到类主体之外,甚至移到不同的文件中,只需通过一个赋值将它们链接到类中。实例化类会像往常一样绑定它们

我的问题很简单,为什么我以前从未见过这种情况?这里有什么东西可能会咬我吗?或者如果它被认为是糟糕的风格,为什么

(如果你想知道我的上下文,那是关于Django视图和表单子类的。我非常希望保持它们的简短,这样它们背后的业务逻辑就很容易理解。我更希望那些只具有表面意义的方法被转移到别处)

就我而言,最大的优点是,我可以将大型方法定义移到类主体之外,甚至移到不同的文件中

我个人不会认为这是“一大优势”。

我的问题很简单,为什么我以前从未见过这种情况

因为这样做的理由很少,而不这样做的理由很多

或者如果它被认为是糟糕的风格,为什么

因为这使得理解发生了什么变得更加困难,非常简单。调试已经够困难的了,你必须浏览的每个文件都会增加“心理负担”

我非常希望它们简短,以便它们背后的业务逻辑易于遵循。我宁愿把那些只具有表面意义的方法搬到别处去

def bar_method(self):
    print( f"in Foo method bar, baz={self.baz}")
    # and pages more code in the real world


class Foo(object):
   def __init__(self):
       self.baz = "Quux"
   bar = bar_method

>>> foo = Foo()
>>> foo.bar()
in Foo method bar, baz=Quux
>>>
然后把重要的部分放在课堂陈述的开头,把装饰性的部分放在结尾

另外,问问自己是否在正确的地方做事情——就我而言,“业务逻辑”主要属于领域层(模型),而“外观”则建议使用表示层(视图/模板)。当然,某些对象(特别是表单和视图)实际上同时处理业务规则和表示,但即使如此,您也可以将此域部分的一部分移动到模型(视图或表单将调用该模型)中,并将此表示部分的一部分移动到模板层(使用过滤器/自定义标记)

我的2美分


NB:如果以上听起来有点傲慢,我很抱歉——我不知道你的代码是什么样子,所以我无法判断你是否已经意识到这一点,并且已经做了正确的事情,只是试图进一步改进,或者你是一个初学者,仍然在为如何实现正确的代码分离而斗争

它的可读性较差,因为如果转到
foo
类,则它不会显示该方法。此外,这里的
\uuu name\uuuu
bar\u方法
,而不是
bar
,并且不清楚这里的
self
是什么。例如,IDE对自动完成
self
没有多大帮助。你问“为什么不”,我问“为什么”?你所发布的“巨大优势”实际上是一个巨大的劣势。想象一下,调试或者甚至试图理解一个跨越5个不同文件的类实现,我并不生气。但问题无法通过将方法移动到类的末尾来避免,因为重要的是遵循从一个视图到另一个视图的流程,而装饰性的方法只是在View1和View2之间设置了障碍。顺便说一句,我发现在数百行代码中上下滚动比单击另一个选项卡或窗口打开另一个文件要麻烦得多。也许只有我。@nigel222:我想你应该看看是否能重构长方法。通常方法不应超过40-50行,20行或更多行已经“可疑”。尝试寻找常见模式,并在助手函数中抽象这些模式。@nigel222是否使用基于类的视图?我必须说,除非我真的需要它们,否则我不会这样做(这几乎是永远不会的)——它们只会让简单的事情变得毫无意义的复杂。但无论如何:如果你的问题是“如何最好地将‘噪音’代码移出我的视野”,那么在没有看到代码的情况下很难回答。哦,是的:很多代码编辑器都有折叠、对象检查器等功能,这使得导航更容易。我也不经常使用这些功能,因为我的编辑器允许我将同一个文件拆分为两个或多个并排视图,这样我就可以轻松地同时看到两个不同的点(并在每个视图中独立导航)。