从前,我写了一个单身班。该实现是一个只包含静态方法的类-我在__init__
上添加了一个异常仅用于说明,我甚至没有__init__
,但稍后需要一个:
class A:
x = 3
def __init__(self): raise Exception('Oh no you did not!')
@staticmethod
def m1():
print(A.x)
@staticmethod
def m2(n):
A.y=8
快进几年,现在我需要创建单例实例-请不要判断:)。要求:
staticmethod
装饰器都需要删除self
参数。你知道吗__init__
方法解决方案可以在原来的类中实现,但我认为这可能是不可能的,因此一个函数获取原来的类并输出一个新的类可能是可行的:
class A:
x = 3 #No need to touch class variable definitions.
def __init__(self): pass #Maybe the init method will be an argument
def m1(self):
print(self.x)
def m2(self,n):
self.y = n
任何动态创建内容的解决方案(不管是否有黑客攻击)都是好的。我目前正在考虑使用inspect
构建这个,尽管我不确定它是否会成功。你知道吗
很难将所有副作用只能影响类本身的静态单例类转换为副作用只能影响实例对象的普通类。但也可以做相反的事情:只需使静态类拥有普通类的唯一实例并将其所有方法调用和属性访问委托给它,就可以将普通类转换为单例静态类。你知道吗
元类可以完成这项工作。这个方法创建一个特殊的属性
_own
来保存它的模型类的实例,显式地为它创建带有适当签名的方法(它还保留docstring,如果有的话),只是将调用委托给_own
,还将所有属性访问委托给_own
在您的示例中,非单例类将是b:
其单一委托人可声明为:
你可以简单地使用它:
对我来说,最大的问题似乎是让方法调用
self.x
而不是A.x
这将是一个愚蠢的想法,但你说黑客修复是可以的,所以我们可以备份类属性的所有值,更改它们以匹配实例属性,然后调用staticmethod,然后还原所有值吗?如果你允许的话,这样的方法可能会奏效:我不确定这是否足够,但我认为下面的修改既可以用作原始单例,也可以用作普通类。有相当多的样板文件,但它是与类隔离的,而不是使用该类的代码。你知道吗
基本上,您将对每个方法执行以下操作:
staticmethod
装饰器*args
替换每个方法的参数列表self = A
,否则设置self = args[0]
。你知道吗*args
的适当元素为每个旧参数手动创建局部变量。你知道吗例如,
A.m1()
结果是print(A.x)
,而a = A(); a.mi()
结果是print(a.x)
。同样地,A.m2(8)
是A.y = 8
,而a.m2(8)
是a.y = 8
。你知道吗我会犹豫是否尝试进一步自动化;与手动更新每个方法相比,您可能会花费更多的时间来识别和解决棘手的问题。你知道吗
相关问题 更多 >
编程相关推荐