self
as the first argument of a class method seems to some habravchanam to be superfluous. Well, if you don't want an explicit self
, you will have an implicit this
! Under the cut, a little magic on pure Python.self
passed explicitly. It seems to me that there are two reasons for this. The first is The Zen of Python , in which it is written in black and white:Explicit is better than implicit (explicit better than implicit).This also applies to the transfer of this object to the method explicitly, through
self
.$
in Perl, arguments
in JS, func_get_args()
in PHP. In Python, there are no such magic variables, everything that is passed to a function is passed explicitly (including via *args
and **kwargs
). So why, for methods that Python processes as ordinary functions, should an exception be made in the form of an implicit self
transfer? # Python 3! def add_this(f): def wrapped(self, *args, **kwargs): f.__globals__['this'] = self return f(*args, **kwargs) return wrapped class C: name = 'Alex' @add_this def say(phrase): print("{} says: {}".format(this.name, phrase)) c = C() c.say('Can you believe it? There is no `self` here!')
Alex says: Can you believe it? There is no `self` here!
add_this
adds the variable this
to the scope of the function, and assigns it the value self
. Recall that __globals__
is a field referencing a dictionary containing global function variables, i.e. The global module namespace in which this function is declared. Thus, the above code is a dirty hack that adds (and overwrites!) The variable this
to the global module space. All this is suitable for our experiments, but save you from writing this in real code! import types class AddThisMeta(type): def __new__(cls, name, bases, classdict): new_classdict = { key: add_this(val) if isinstance(val, types.FunctionType) else val for key, val in classdict.items() } new_class = type.__new__(cls, name, bases, new_classdict) return new_class class D(metaclass=AddThisMeta): name = 'Daniel' def say(phrase): print("{} says: {}".format(this.name, phrase)) def run(): print("{} runs away :)".format(this.name)) d = D() d.say('And now, there is only AddThisMeta!') d.run()
Daniel says: And now, there is only AddThisMeta! Daniel runs away :)
callable()
will not work, because it will also work for the classmethod
and staticmethod
) and frames these functions with the add_this
decorator.self
(or this
) to class methods is not at all difficult. But please, for the good of everything in Python, never, never , never do it.Source: https://habr.com/ru/post/257887/
All Articles