jle*_*hon 6 python lazy-evaluation class-method python-3.x
我正在使用Python 3.我知道@classmethod装饰器.另外,我知道可以从实例调用classmethods.
class HappyClass(object):
@classmethod
def say_hello():
print('hello')
HappyClass.say_hello() # hello
HappyClass().say_hello() # hello
Run Code Online (Sandbox Code Playgroud)
但是,我似乎无法动态创建类方法并让它们从实例中调用.假设我想要类似的东西
class SadClass(object):
def __init__(self, *args, **kwargs):
# create a class method say_dynamic
SadClass.say_dynamic() # prints "dynamic!"
SadClass().say_dynamic() # prints "dynamic!"
Run Code Online (Sandbox Code Playgroud)
我玩过cls.__dict__(产生异常),并且setattr(cls, 'say_dynamic', blahblah)(只使得这个东西可以从类而不是实例中调用).
如果你问我为什么,我想做一个懒惰的类属性.但它不能从实例中调用.
@classmethod
def search_url(cls):
if hasattr(cls, '_search_url'):
setattr(cls, '_search_url', reverse('%s-search' % cls._meta.model_name))
return cls._search_url
Run Code Online (Sandbox Code Playgroud)
也许是因为这个属性还没有从课堂上调出来......
综上所述,我想添加一个懒惰,类方法,可以从实例调用 ......可这在一个优雅(nottoomanylines)的方式来实现?
有什么想法吗?
我是如何实现它的
对不起,我的例子非常糟糕:
无论如何,最后我这样做了......
@classmethod
def search_url(cls):
if not hasattr(cls, '_search_url'):
setattr(cls, '_search_url', reverse('%s-search' % cls._meta.model_name))
return cls._search_url
Run Code Online (Sandbox Code Playgroud)
而setattr工作,但测试时我犯了一个错误?
您可以在任何时候向类添加一个函数,这种做法称为猴子修补:
class SadClass:
pass
@classmethod
def say_dynamic(cls):
print('hello')
SadClass.say_dynamic = say_dynamic
>>> SadClass.say_dynamic()
hello
>>> SadClass().say_dynamic()
hello
Run Code Online (Sandbox Code Playgroud)
请注意,您正在使用classmethod装饰器,但您的函数不接受任何参数,这表明它被设计为静态方法.你的意思是staticmethod代替吗?
如果要创建类方法,请不要在__init__函数中创建它们,因为它会为每个实例创建重新创建。但是,以下工作:
class SadClass(object):
pass
def say_dynamic(cls):
print("dynamic")
SadClass.say_dynamic = classmethod(say_dynamic)
# or
setattr(SadClass, 'say_dynamic', classmethod(say_dynamic))
SadClass.say_dynamic() # prints "dynamic!"
SadClass().say_dynamic() # prints "dynamic!"
Run Code Online (Sandbox Code Playgroud)
当然,在__init__方法中,self参数是一个实例,而不是类:要将方法放在那里的类中,您可以破解类似
class SadClass(object):
def __init__(self, *args, **kwargs):
@classmethod
def say_dynamic(cls):
print("dynamic!")
setattr(self.__class__, 'say_dynamic', say_dynamic)
Run Code Online (Sandbox Code Playgroud)
但它会再次为每个实例创建重置方法,可能是不必要的。请注意,您的代码很可能会失败,因为您SadClass.say_dynamic()在创建任何实例之前调用了,因此在注入类方法之前。
另外,请注意 aclassmethod获取隐式类参数cls;如果您确实希望在没有任何参数的情况下调用您的函数,请使用staticmethod装饰器。
jle*_*hon -1
我是如何实现的:
@classmethod
def search_url(cls):
if not hasattr(cls, '_search_url'):
setattr(cls, '_search_url', reverse('%s-search' % cls._meta.model_name))
return cls._search_url
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3577 次 |
| 最近记录: |