Lon*_*ner 6 python static-methods python-3.x
我试图了解静态方法如何在内部工作.我知道如何使用@staticmethod装饰器,但我将避免在这篇文章中使用它,以深入了解静态方法的工作原理并提出我的问题.
从我了解的Python,如果有一类A,然后调用A.foo()调用foo()不带任何参数,而调用A().foo()调用foo()一个说法,其中一个说法是实例A()本身.
但是,在静态方法的情况下,似乎总是foo()在没有参数的情况下调用它是否称为A.foo()或A().foo().
证明如下:
>>> class A:
... x = 'hi'
... def foo():
... print('hello, world')
... bar = staticmethod(foo)
...
>>> A.bar()
hello, world
>>> A().bar()
hello, world
>>> A.bar
<function A.foo at 0x00000000005927B8>
>>> A().bar
<function A.foo at 0x00000000005927B8>
>>> A.bar(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes 0 positional arguments but 1 was given
>>> A().bar(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes 0 positional arguments but 1 was given
Run Code Online (Sandbox Code Playgroud)
所以我是否正确地得出结论,该staticmethod()函数具有一些魔力,foo()总是用0参数调用?
如果我staticmethod()在自己的Python代码中定义自己的代码,我该怎么做?甚至可以从我们自己的Python代码中定义这样的方法,还是只能将这样的函数定义为内置函数?
它被实现为描述符.例如:
In [1]: class MyStaticMethod(object):
...: def __init__(self, func):
...: self._func = func
...: def __get__(self, inst, cls):
...: return self._func
...:
In [2]: class A(object):
...: @MyStaticMethod
...: def foo():
...: print('Hello, World!')
...:
In [3]: A.foo()
Hello, World!
In [4]: A().foo()
Hello, World!
Run Code Online (Sandbox Code Playgroud)
以同样的方式定义classmethod,只需传递cls给原始函数:
In [5]: from functools import partial
...:
...: class MyClassMethod(object):
...: def __init__(self, func):
...: self._func = func
...: def __get__(self, inst, cls):
...: return partial(self._func, cls)
In [6]: class A(object):
...: @MyClassMethod
...: def foo(cls):
...: print('In class: {}'.format(cls))
...:
In [7]: A.foo()
In class: <class '__main__.A'>
In [8]: A().foo()
In class: <class '__main__.A'>
Run Code Online (Sandbox Code Playgroud)
方法(包括实例,静态和类方法)通过描述符协议工作.如果类dict中的对象实现了__get__特殊方法:
class Descriptor(object):
def __get__(self, instance, klass):
return instance, klass
class HasDescriptor(object):
descriptor = Descriptor()
x = HasDescriptor()
Run Code Online (Sandbox Code Playgroud)
然后以下属性访问:
x.descriptor
HasDescriptor.descriptor
Run Code Online (Sandbox Code Playgroud)
将调用描述符的__get__方法来计算它们的值,如下所示:
descriptor.__get__(x, HasDescriptor)
descriptor.__get__(None, HasDescriptor)
Run Code Online (Sandbox Code Playgroud)
函数,staticmethod以及classmethod所有实现__get__方法访问的工具.你也可以做到的:
class MyStaticMethod(object):
def __init__(self, f):
self.f = f
def __get__(self, instance, klass):
return self.f
Run Code Online (Sandbox Code Playgroud)
也有__set__和__delete__,使您可以分别控制设置和删除属性,方法.方法不使用这些,但property确实如此.
| 归档时间: |
|
| 查看次数: |
208 次 |
| 最近记录: |