- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个装饰器叫做 Special
将函数转换为自身的两个版本:一个可以直接调用并在结果前加上前缀 'regular '
和一个可以用 .special
调用的并在结果前加上 'special '
前缀:
class Special:
def __init__(self, func):
self.func = func
def __get__(self, instance, owner=None):
if instance is None:
return self
return Special(self.func.__get__(instance, owner))
def special(self, *args, **kwargs):
return 'special ' + self.func(*args, **kwargs)
def __call__(self, *args, **kwargs):
return 'regular ' + self.func(*args, **kwargs)
它适用于常规方法和静态方法 - 但 .special
不适用于类方法:
class Foo:
@Special
def bar(self):
return 'bar'
@staticmethod
@Special
def baz():
return 'baz'
@classmethod
@Special
def qux(cls):
return 'qux'
assert Foo().bar() == 'regular bar'
assert Foo().bar.special() == 'special bar'
assert Foo.baz() == 'regular baz'
assert Foo.baz.special() == 'special baz'
assert Foo.qux() == 'regular qux'
assert Foo.qux.special() == 'special qux' # TypeError: qux() missing 1 required positional argument: 'cls'
Foo().bar
正在调用 __get__
, 它绑定(bind)底层函数并将绑定(bind)方法传递给 Special
的新实例- 这就是为什么 Foo().bar()
和 Foo().bar.special()
工作。
Foo.baz
只是返回原来的 Special
实例 - 常规调用和特殊调用都很简单。
Foo.qux
无需调用我的 __get__
即可绑定(bind).
Foo.qux()
有效。Foo.qux.special
只是调用 .special
底层函数(classmethod
不知道如何绑定(bind)它)- 所以 Foo.qux.special()
正在调用未绑定(bind)函数,因此 TypeError
.Foo.qux.special
有什么办法吗?知道它是从 classmethod
调用的?或者解决这个问题的其他方法?
最佳答案
classmethod
是一个返回绑定(bind)方法的描述符。它不会在此过程中调用您的 __get__
方法,因为它不能在不破坏描述符协议(protocol)的某些约定的情况下这样做。 (也就是说,instance
应该是一个实例,而不是一个类。)所以您的 __get__
方法没有被调用是完全可以预料的。
那么如何让它发挥作用呢?好吧,想一想:您希望 some_instance.bar
和 SomeClass.bar
都返回一个 Special
实例。为了实现这一点,您只需应用 @Special
装饰器 last:
class Foo:
@Special
@staticmethod
def baz():
return 'baz'
@Special
@classmethod
def qux(cls):
return 'qux'
这使您可以完全控制是否/何时/如何调用装饰函数的描述符协议(protocol)。现在您只需要删除 if instance is None:
方法中的 __get__
特例,因为它会阻止类方法正常工作。 (原因是 classmethod 对象是不可调用的;你必须调用描述符协议(protocol)将 classmethod 对象变成一个可以调用的函数。)换句话说,Special.__get__
方法必须无条件调用修饰函数的 __get__
方法,如下所示:
def __get__(self, instance=None, owner=None):
return Special(self.func.__get__(instance, owner))
现在您所有的断言都将通过。
关于python - @classmethod 没有调用我的自定义描述符的 __get__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50847358/
根据Python docs : If a class method is called for a derived class, the derived class object is passed
假设我有一个类 class SimpleGenerator(object): @classmethod def get_description(cls): return
我必须使用一些 Python 库,其中包含具有各种实用程序的文件:类和方法。其中一种方法以下列方式定义(我不能放完整代码): @classmethod def do_something(cls, ar
在 Python 中,我可以使用 @classmethod 创建一个类方法。装饰师: >>> class C: ... @classmethod ... def f(cls): ...
我通常使用 isinstance 进行构造函数重载,但人们也建议使用 @classmethod 来实现相同的目的。但据我所知,@classmethod 共享该变量。 下面是一个简单的类 class a
遇到这个难题时,我正在学习 Python 中的类和对象。下面是相同代码的两种情况,一种没有@classmethod,另一种有@classmethod: #without @classmethod >>
装饰器classmethod的源代码在python源码在哪里。具体来说,我无法找到它在 2.7.2 版中定义的确切文件 最佳答案 我没有回答你的问题 - 但下面的代码显示了用纯 Python 编写的等
TL;DR 如何确定一个函数是使用 @classmethod 还是具有相同效果的东西定义的? 我的问题 为了实现一个类装饰器,我想检查一个方法是否将类作为它的第一个参数,例如通过 @classmeth
我有以下 Python 元类,它为每个类添加了一个 deco_with_args 装饰器: def deco_with_args(baz): def decorator(func):
我想使用@classmethod,但我不想用它污染实例的命名空间。如果我有一个类方法 for_classes_only,如何防止实例获取它? class MyThing(object): de
这个问题已经有答案了: What is the purpose of class methods? (18 个回答) 已关闭 4 年前。 我观看了一个 YouTube 视频,解释了 @classmet
这更像是一个过程问题,但我现在用 Python 编程已经有一段时间了,我试图理解单元测试、功能测试之间的区别,以及何时适本地使用模拟以便测试功能。我有以下安排: @classmethod def ge
据说: When it would yield a class method object, it is transformed into a bound user-defined method ob
我尝试在带有装饰器@classmethod 的方法中调用方法,知道如何实现吗?例如我有: class A(): def B(self): #do something retur
我有以下代码来查找数据库中的对象实例,然后使用数据创建 python 对象。 class Parent: @staticmethod def get(table, **kwargs):
我有这个谷歌应用程序引擎数据存储区 NDB 模型: class pySessions(ndb.Model): # sid is the key/id data = ndb.Blobpr
我有一个装饰器叫做 Special将函数转换为自身的两个版本:一个可以直接调用并在结果前加上前缀 'regular '和一个可以用 .special 调用的并在结果前加上 'special ' 前缀:
我想猴子修补一个类方法,保留旧功能。考虑我的代码来理解这个想法。这是我的代码(非常综合的例子)。 #!/usr/bin/env python class A: @classmethod def
我在 python 中基本上有以下内容: class X(object): pass class Y(object): @classmethod def method(cls, x_inst,
我有以下代码: class ObjectOne(object): @classmethod def print_class_name(cls): print cls._
我是一名优秀的程序员,十分优秀!