虽然有一些针对OP情况的答案,合理地建议不要从类中调用实例方法,
但我有一个类似的用例,确实需要从同一个类中调用实例方法。
因为这是不可能的,或者说是一种取巧的方法,我已经找到了一种解决办法。
我认为这可能是最简单的合理方法,但如果有任何改进或修正,那将是非常好的。
用例演示(不可用)
class MyClass:
context = {"a": 1}
def __init__(self, details):
self.details = details
def get(self, key):
val = self.details.get(key)
if val is None:
val = self.context.get(key)
return val
my = MyClass({"a": 2})
print(my.get("a"))
print(MyClass.get("a"))
从实例运行这个可以工作,但从类运行不起作用。
这展示了所寻求的大致功能。
" a "参数被分配给" self "参数,Python 抱怨没有参数留给" key "参数。
2
Traceback (most recent call last):
File "myclass.py", line 17, in <module>
print(MyClass.get("a"))
TypeError: MyClass.get() missing 1 required positional argument: 'key'
解决方案概念
需要一个同名的独立类方法和实例方法。
但是,在同一对象上定义两个同名方法只能意味着后定义的方法会覆盖先定义的方法。一个单一对象肯定不会支持两个同名的不同属性。
解决方案是在不同的对象上有两个独立的同名方法。一个是普通的类方法,一个是普通的实例方法。
解决方案设计
为了实现这一点,可以引入一个子类,让子类重新定义同名方法。Python面向对象编程会适当地调用它们。
class MyClass:
context = {"a": 1}
@classmethod
def get(cls, key):
val = cls.context.get(key)
return val
class MySubClass(MyClass):
def __init__(self, details):
self.details = details
def get(self, key):
val = self.details.get(key)
if val is None:
val = self.__class__.get(key)
return val
my = MySubClass({"a": 2})
print(my.get("a"))
print(MyClass.get("a"))
这个解决方案有效。
2
1
类的单例行为仍然可用,但不再创建该类的实例,而是使用子类的实例。
这意味着需要定义一个额外的子类,并且需要将方法的实现分散开来,但这似乎是必要且适当的,以处理类和实例之间的差异。
get_params
也设为类方法? - BrenBarnMyClass
只是一个例子,get_params
代表一个在我的类中被很多实例方法调用的方法,我认为应该有一种方式可以从classmethod
中调用它,而不用改变当前调用它的所有方法。无论如何,谢谢 :) - Gerardget_params
是做什么的?如果它是一个实例方法,你需要有一个实例才能调用它。如果没有,它可能不应该是一个实例方法。但你可以通过将类的实例作为显式的第一个参数来从任何其他范围调用实例方法。 - Silas Rayget_params
设置为classmethod
不应该破坏任何调用instance.get_params()
的代码。但是,它会破坏那些只调用TheClass.get_params(instance)
的代码。 - Bakuriuget_params
不需要访问实例,则将其设置为类方法即可。这可能需要在其他地方进行一些更改,但是没有其他办法。请注意,您可以从实例方法中无问题地调用类方法,因此您实际上可能不必进行太多更改。 - BrenBarn