- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 python 中基本上有以下内容:
class X(object): pass
class Y(object):
@classmethod
def method(cls, x_inst, *args, **kwargs):
#do some work here that requires an instance of x
pass
我想做的是为 X
的所有实例添加一个动态属性,允许访问 Y
隐式填充 方法的第一个参数
与给定的实例。例如,我希望以下代码能够以相同的方式工作:
# current
x = X()
result = Y.method(x, 1, 2, 3)
# desired
x = X()
x.Y.method(1, 2, 3)
我想为几个子类实现此行为的几个方法。我目前所做的是创建一个 YProxy
类,X
实际返回,然后将一些代码拆分到其中。然而,它看起来相当不优雅且难以维护:
class X(object):
@property
def Y(self):
return YProxy(self)
class Y(object):
@classmethod
def method(cls, x_inst, *args, **kwargs):
#do some work here that requires an instance of x
pass
class YProxy(object):
def __init__(self, x_inst):
self.x_inst = x_inst
def method(self, *args, **kwargs):
return Y.method(self.x_inst, *args, **kwargs)
有没有办法有条件地部分评估对象的类方法?
最佳答案
这可以通过 Descriptor 对象 + 包装类广告来完成,并明确声明您需要以这种方式在目标类上包装的类。
描述符对象是定义 __get__
的任何对象方法,当描述符是类的一部分时,它允许自定义属性检索。在这种情况下,我们希望当从实例中检索该属性(即“Y”类)时,无论何时从该类中检索方法,都将该实例插入到参数列表中。
这要求检索到的属性本身是具有自定义属性访问权限的“代理”类,以允许动态包装进行记录。
将所有这些翻译成 Python,我们有:
import types
from functools import partial
class APIWrapper(object):
def __init__(self, apicls, instance):
self._apicls = apicls
self._instance = instance
def __getattribute__(self, attr):
apicls = object.__getattribute__(self, "_apicls")
instance = object.__getattribute__(self,"_instance")
obj = getattr(apicls, attr)
if isinstance(obj, types.MethodType):
return partial(obj,instance)
return obj
class APIProperty(object):
def __init__(self, cls):
self.cls = cls
def __get__(self, instance, cls):
return APIWrapper(self.cls, instance)
class Y(object):
@classmethod
def method(cls, x, *args):
print cls, x, args
class X(object):
Y = APIProperty(Y)
#Example usage:
x = X()
x.Y.method(1,2,3)
(运行时打印 <class '__main__.Y'> <__main__.X object at 0x18ad090> (1, 2, 3)
)
但我想你不想写
Y = APIWrapper(Y)
对于您要以这种方式包装的每个类。 (并在包装类之后定义这些类,以便在解析 X 主体时已经解析了 Y)。
这可以通过元类、类装饰器来完成,它们必须为您想要应用方法的每个类定义 - 相反,我创建了一个函数,该函数将在模块定义的末尾调用,在您定义“X”类的位置-此函数将为每个定义的类添加所需的类作为属性(在我的示例中,我希望该类标有“auto_api”属性-但适合您自己)-于是,“auto_api”函数,X类和Y类的定义就变成了这样(使用和上面一样的APIProperty和APIWrapper)
def auto_api(api_classes, glob_dict):
for key, value in glob_dict.items():
if isinstance(value, type) and hasattr(value, "auto_api"):
for api_class in api_classes:
setattr(value, api_class.__name__, APIProperty(api_class))
class X(object):
auto_api = True
class Y(object):
@classmethod
def method(cls, x, *args):
print cls, x, args
auto_api((Y,), globals())
#Example
x = X()
x.Y.method(1,2,3)
关于python - 根据访问的位置部分评估 Python Classmethod,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8957408/
根据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._
我是一名优秀的程序员,十分优秀!