结合从类方法和实例方法调用的类似方法的Pythonic方法
Pythonic way to combine simillar methods called from classmethod and instance method
我有一个 class 方法和 class 方法来创建图形。 class 在 class 和实例级别上也有一个属性 auto_show
。用于决定创建的图形是否自动显示。现在我需要两种不同的方法来实现这一点:
class MyClass:
auto_show = True
...
def __init__(self, ...):
self.auto_show = MyClass.auto_show
...
@classmethod
def _class_auto_show_figure(cls, fig):
"""Should be used only for class methods"""
if cls.auto_show:
fig.show()
def _auto_show_figure(self, fig):
if self.auto_show:
fig.show()
现在第一个在所有 class 方法中调用,第二个在所有实例方法中调用。我想将它们组合成一个方法,但找不到令人满意的方法。有没有好的解决方案,或者我应该坚持使用两种不同的方法来做基本相同的事情? (顺便说一句,与 class 属性相比,实例可以具有不同的 auto_show
值很重要。)
您可以通过以下方式使用一个函数来完成此操作:
class MyClass:
auto_show = True
def __init__(self):
self.auto_show = MyClass.auto_show # can be changed to (obj.__class__).auto_show
def fun(self=None):
if self==None:
print("class auto_show:", MyClass.auto_show)
else:
print("instance auto_show:", self.auto_show)
obj=MyClass()
MyClass.fun()
out: class auto_show: True
obj.fun()
out: instance auto_show: True
obj.auto_show = False
MyClass.fun()
out: class auto_show: True
obj.fun()
instance auto_show: False
检查此方法是否符合您的要求。
这是一个使用 descriptor protocol 的解决方案:
from functools import partial
class ClassOrInstanceMethod:
def __init__(self, f):
self.f = f
def __get__(self, instance, cls=None):
return partial(self.f, cls, instance)
class Foo:
data = 'Foo class data'
def __init__(self, data):
self.data = data
@ClassOrInstanceMethod
def test(cls, instance):
if instance is None:
print(cls.data)
else:
print(instance.data)
class Bar(Foo):
data = 'Bar class data'
Foo.test() # prints 'Foo class data'
Bar.test() # prints 'Bar class data'
Foo('Foo instance data').test() # prints 'Foo instance data'
Bar('Bar instance data').test() # prints 'Bar instance data'
我有一个 class 方法和 class 方法来创建图形。 class 在 class 和实例级别上也有一个属性 auto_show
。用于决定创建的图形是否自动显示。现在我需要两种不同的方法来实现这一点:
class MyClass:
auto_show = True
...
def __init__(self, ...):
self.auto_show = MyClass.auto_show
...
@classmethod
def _class_auto_show_figure(cls, fig):
"""Should be used only for class methods"""
if cls.auto_show:
fig.show()
def _auto_show_figure(self, fig):
if self.auto_show:
fig.show()
现在第一个在所有 class 方法中调用,第二个在所有实例方法中调用。我想将它们组合成一个方法,但找不到令人满意的方法。有没有好的解决方案,或者我应该坚持使用两种不同的方法来做基本相同的事情? (顺便说一句,与 class 属性相比,实例可以具有不同的 auto_show
值很重要。)
您可以通过以下方式使用一个函数来完成此操作:
class MyClass:
auto_show = True
def __init__(self):
self.auto_show = MyClass.auto_show # can be changed to (obj.__class__).auto_show
def fun(self=None):
if self==None:
print("class auto_show:", MyClass.auto_show)
else:
print("instance auto_show:", self.auto_show)
obj=MyClass()
MyClass.fun()
out: class auto_show: True
obj.fun()
out: instance auto_show: True
obj.auto_show = False
MyClass.fun()
out: class auto_show: True
obj.fun()
instance auto_show: False
检查此方法是否符合您的要求。
这是一个使用 descriptor protocol 的解决方案:
from functools import partial
class ClassOrInstanceMethod:
def __init__(self, f):
self.f = f
def __get__(self, instance, cls=None):
return partial(self.f, cls, instance)
class Foo:
data = 'Foo class data'
def __init__(self, data):
self.data = data
@ClassOrInstanceMethod
def test(cls, instance):
if instance is None:
print(cls.data)
else:
print(instance.data)
class Bar(Foo):
data = 'Bar class data'
Foo.test() # prints 'Foo class data'
Bar.test() # prints 'Bar class data'
Foo('Foo instance data').test() # prints 'Foo instance data'
Bar('Bar instance data').test() # prints 'Bar instance data'