Rea*_*nly 187 python oop methods self
在Python中定义类的方法时,它看起来像这样:
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
Run Code Online (Sandbox Code Playgroud)
但是在其他一些语言中,例如C#,您可以使用"this"关键字引用该方法绑定的对象,而不将其声明为方法原型中的参数.
这是一个有意的语言设计决策在Python或是否有一些实现细节需要传递"自我"作为参数?
S.L*_*ott 89
我想引用Peters的Python禅."明确比隐含更好."
在Java和C++中,this.可以推导出' ',除非你有可变名称使其无法推断.所以你有时需要它,有时却不需要它.
Python选择将这样的内容显式化而不是基于规则.
此外,由于没有暗示或假设任何内容,因此公开了部分实现. self.__class__,self.__dict__和其他"内部"结构,一个明显的方式可供选择.
Rya*_*yan 58
这是为了最小化方法和功能之间的差异.它允许您轻松地在元类中生成方法,或者在运行时将方法添加到预先存在的类中.
例如
>>> 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!
>>>
Run Code Online (Sandbox Code Playgroud)
它(据我所知)也使python运行时的实现更容易.
bha*_*dra 52
我建议人们应该阅读Guido van Rossum关于这个话题的博客 - 为什么明确的自我必须留下来.
当一个方法定义被装饰时,我们不知道是否自动给它一个'self'参数:装饰器可以将函数转换为静态方法(没有'self'),或者类方法(有一种有趣的自我,指的是一个类而不是一个实例),或者它可以做一些完全不同的事情(编写一个在纯Python中实现'@classmethod'或'@staticmethod'的装饰器是微不足道的).如果不知道装饰器是否赋予使用隐式"自"参数定义的方法的作用,就没有办法.
我拒绝像特殊套管'@classmethod'和'@staticmethod'这样的黑客攻击.
Vic*_*dji 16
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
Run Code Online (Sandbox Code Playgroud)
当然,在Java和C#等语言中难以想象.通过使自引用显式化,您可以通过该自引用自由引用任何对象.此外,这种在运行时使用类的方法在更静态的语言中更难做到 - 不一定是好或坏.只是明确的自我允许所有这些疯狂存在.
而且,想象一下:我们想定制方法的行为(用于分析,或者一些疯狂的黑魔法).这可以引导我们思考:如果我们有一个Method我们可以覆盖或控制其行为的类怎么办?
那么这里是:
from functools import partial
class MagicMethod(object):
"""Does black magic when called"""
def __get__(self, obj, obj_type):
# This binds the <other> class instance to the <innocent_self> 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()
Run Code Online (Sandbox Code Playgroud)
而现在:InnocentClass().magic_method()将表现得像预期的那样.该方法将与innocent_self参数绑定InnocentClass,并与magic_selfMagicMethod实例绑定.怪啊?这就像有两个关键字this1和this2Java和C#等语言.像这样的魔法允许框架做一些本来会更冗长的东西.
同样,我不想评论这些东西的道德规范.我只是想展示一些没有明确的自我引用会更难做的事情.
我认为这与 PEP 227 有关:
类范围内的名称不可访问。名称在最内层的函数作用域中解析。如果类定义出现在嵌套作用域链中,则解析过程会跳过类定义。此规则可防止类属性和局部变量访问之间出现奇怪的交互。如果名称绑定操作发生在类定义中,它将在生成的类对象上创建一个属性。要在方法中或在方法中嵌套的函数中访问此变量,必须通过 self 或通过类名使用属性引用。