我有这些与@property
def android(**params):
def deco(f):
def wrap(*args, **kwargs):
if is_android:
return params
return f()
return wrap
return deco
def ios(**params):
def deco(f):
def wrap(*args, **kwargs):
if not is_android:
return params
return f()
return wrap
return deco
定义了类:
class Foo:
@property
@android(foo=1)
@ios(foo=2)
def foo(self):
pass
f = Foo()
print(f.foo)
每次我想使用时,我都要一次又一次地重复@property
。有没有办法将@property
合并到@android
和@ios
?我的意思是只需使用@android
和@ios
而不@property
,但我可以致电f.foo
答案 0 :(得分:1)
您可以修改装饰器以返回property
个对象。但是,除非您只想为它们支持单个特定的顺序,否则您需要使它们的逻辑更复杂,以便它们即使应用它们的“函数”已经是属性对象也能工作。这是我认为应该做的一个未经测试的装饰器更新:
def android(**params):
def deco(f):
if isinstance(f, property):
prop = f.getter
f = f.fget
else:
prop = property
def wrap(*args, **kwargs):
if is_android:
return params
return f()
return prop(wrap)
return deco
但我不确定这是不是最好的方法。您的代码不会使用您装饰的foo
函数。其中一个装饰者总是拦截这个电话。如果您的真实代码是真的,我建议编写您自己的描述符类型,而不是打扰property
或装饰器。这是一个相当简单的自定义描述符示例,它将值在android和IOS中作为参数返回(并且它在类中使用):
class MyDescriptor:
def __init__(self, android_value, ios_value):
self.android_value = android_value
self.ios_value = ios_value
def __get__(self, instance, owner)
if is_android:
return self.android_value
else:
return self.ios_value
def __set__(self, instance, value):
raise NotImplementedError()
class Foo:
foo = MyDescriptor({"foo": 1}, {"foo": 2})
如果is_android
值是常量,并且在定义类时您将知道其值,您甚至可以进一步简化事物。在这种情况下,您可以只分配一个普通的类变量,使用条件逻辑根据需要修改值:
class Foo:
foo = {"foo": 1 if is_android else 2}
答案 1 :(得分:1)
我认为您需要使用类装饰器来修改您的类,使属性成为类字段。
is_android = True
def android(**params):
def deco(f):
def wrap(*args, **kwargs):
if is_android:
return params
return f()
wrap.__decorated_by_mobile__ = True
return wrap
return deco
def ios(**params):
def deco(f):
f.wrapped = True
def wrap(*args, **kwargs):
if not is_android:
return params
return f()
wrap.__decorated_by_mobile__ = True
return wrap
return deco
def class_deco(cls):
for name, method in cls.__dict__.items():
if callable(method):
if hasattr(method, '__decorated_by_mobile__'):
setattr(cls, name, method())
return cls
@class_deco
class Foo:
@android(a=1)
@ios(a=2)
def foo(self):
pass
f = Foo()
print(f.foo)
希望这是你正在寻找的东西:)