在Python中定义类的方法时,它看起来像这样:
class MyClass(object): def __init__(self, x, y): self.x = x self.y = y
但是在其他一些语言中,例如C#,您可以使用"this"关键字引用该方法绑定的对象,而不将其声明为方法原型中的参数.
这是一个有意的语言设计决策在Python或是否有一些实现细节需要传递"自我"作为参数?
我想引用Peters的Python禅."明确比隐含更好."
在Java和C++中,this.
可以推导出' ',除非你有可变名称使其无法推断.所以你有时需要它,有时却不需要它.
Python选择将这样的内容显式化而不是基于规则.
此外,由于没有暗示或假设任何内容,因此公开了部分实现. self.__class__
,self.__dict__
和其他"内部"结构,一个明显的方式可供选择.
这是为了最小化方法和功能之间的差异.它允许您轻松地在元类中生成方法,或者在运行时将方法添加到预先存在的类中.
例如
>>> class C(object): ... def foo(self): ... print "Hi!" ... >>> >>> def bar(self): ... print "Bork bork bork!" ... >>> >>> c = C() >>> C.bar = bar >>> c.bar() Bork bork bork! >>> c.foo() Hi! >>>
它(据我所知)也使python运行时的实现更容易.
我建议人们应该阅读Guido van Rossum关于这个话题的博客 - 为什么明确的自我必须留下来.
当一个方法定义被装饰时,我们不知道是否自动给它一个'self'参数:装饰器可以将函数转换为静态方法(没有'self'),或者类方法(有一种有趣的自我,指的是一个类而不是一个实例),或者它可以做一些完全不同的事情(编写一个在纯Python中实现'@classmethod'或'@staticmethod'的装饰器是微不足道的).如果不知道装饰器是否赋予使用隐式"自"参数定义的方法的作用,就没有办法.
我拒绝像特殊套管'@classmethod'和'@staticmethod'这样的黑客攻击.
Python不会强迫你使用"自我".你可以给它任何你想要的名字.您只需记住方法定义标头中的第一个参数是对该对象的引用.
也允许你这样做:(简而言之,调用Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5)
将返回12,但将以最疯狂的方式执行此操作.
class Outer(object): def __init__(self, outer_num): self.outer_num = outer_num def create_inner_class(outer_self, inner_arg): class Inner(object): inner_arg = inner_arg def weird_sum_with_closure_scope(inner_self, num) return num + outer_self.outer_num + inner_arg return Inner
当然,在Java和C#等语言中难以想象.通过使自引用显式化,您可以通过该自引用自由引用任何对象.此外,这种在运行时使用类的方法在更静态的语言中更难做到 - 不一定是好或坏.只是明确的自我允许所有这些疯狂存在.
而且,想象一下:我们想定制方法的行为(用于分析,或者一些疯狂的黑魔法).这可以引导我们思考:如果我们有一个Method
我们可以覆盖或控制其行为的类怎么办?
那么这里是:
from functools import partial class MagicMethod(object): """Does black magic when called""" def __get__(self, obj, obj_type): # This binds theclass instance to the parameter # of the method MagicMethod.invoke return partial(self.invoke, obj) def invoke(magic_self, innocent_self, *args, **kwargs): # do black magic here ... print magic_self, innocent_self, args, kwargs class InnocentClass(object): magic_method = MagicMethod()
而现在:InnocentClass().magic_method()
将表现得像预期的那样.该方法将与innocent_self
参数绑定InnocentClass
,并与magic_self
MagicMethod实例绑定.怪啊?这就像有两个关键字this1
和this2
Java和C#等语言.像这样的魔法允许框架做一些本来会更冗长的东西.
同样,我不想评论这些东西的道德规范.我只是想展示一些没有明确的自我引用会更难做的事情.