- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Python 中,我可以使用 @classmethod
创建一个类方法。装饰师:
>>> class C:
... @classmethod
... def f(cls):
... print(f'f called with cls={cls}')
...
>>> C.f()
f called with cls=<class '__main__.C'>
>>> class M(type):
... def f(cls):
... print(f'f called with cls={cls}')
...
>>> class C(metaclass=M):
... pass
...
>>> C.f()
f called with cls=<class '__main__.C'>
C.f()
的输出所示,这两种方法提供了类似的功能。
@classmethod
有什么区别?并在元类上使用普通方法?
最佳答案
由于类是元类的实例,因此元类上的“实例方法”的行为类似于类方法也就不足为奇了。
但是,是的,存在差异——其中一些不仅仅是语义上的:
abc.ABCMeta.register
中使用了这个特性。方法。__get__
插入
self
的方法从实例中检索它们时的参数,并在从类中检索时将该参数留空,
classmethod
对象有不同的
__get__
,这将在这两种情况下插入类本身(“所有者”)作为第一个参数。
meta.method
检索函数,准备使用,而您必须使用
cls.my_classmethod.__func__
从类方法中检索它(然后您必须创建另一个
classmethod
对象并将其分配回,如果您进行一些包装)。
class M1(type):
def clsmethod1(cls):
pass
class CLS1(metaclass=M1):
pass
def runtime_wrap(cls, method_name, wrapper):
mcls = type(cls)
setattr(mcls, method_name, wrapper(getatttr(mcls, method_name)))
def wrapper(classmethod):
def new_method(cls):
print("wrapper called")
return classmethod(cls)
return new_method
runtime_wrap(cls1, "clsmethod1", wrapper)
class CLS2:
@classmethod
def classmethod2(cls):
pass
def runtime_wrap2(cls, method_name, wrapper):
setattr(cls, method_name, classmethod(
wrapper(getatttr(cls, method_name).__func__)
)
)
runtime_wrap2(cls1, "clsmethod1", wrapper)
classmethod
对象不这样做,其他差异在运行时会显得晦涩和无意义 - 但发生这种情况是因为语言不需要使用类方法的特殊规则:两种声明类方法的方式都是可能的,结果来自语言设计 - 一个是因为一个类本身就是一个对象,另一个是使用描述符协议(protocol)的可能性,它允许在实例和类中专门化属性访问:
classmethod
builtin 是在 native 代码中定义的,但它可以只用纯 python 编码并且以完全相同的方式工作。下面的 5 行类可用作
classmethod
与内置
@classmethod" at all (though distinguishable through introspection such as calls to
没有运行时差异的装饰器实例
, and even
repr`当然):
class myclassmethod:
def __init__(self, func):
self.__func__ = func
def __get__(self, instance, owner):
return lambda *args, **kw: self.__func__(owner, *args, **kw)
@property
之类的专用属性。在元类上将作为专门的类属性工作,完全一样,没有任何令人惊讶的行为。
关于python - `classmethod` 和元类方法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59341761/
根据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._
我是一名优秀的程序员,十分优秀!