我有一个关于python中基于类的装饰器以及参数如何的问题 可以在装饰给定功能时提供。
考虑以下原型:
class MyDecoratorClass:
def __init__(self, *args, **kwargs):
# . . . Any code that is needed here
pass
def __call__(self, fun_to_decorate, *args, **kwargs):
def inner(*args, **kwargs):
# . . . Any code that is needed here
return fun_to_decorate(*args, **kwargs)
return inner
考虑要装饰的功能:
def myfun(*args, **kwargs):
print("myfun was called")
装饰上述功能的一种方法如下:
第1步:创建装饰器类的实例。这会打电话给
构造函数,即__init__
。如果我通过任何论点
在下面,它只会出现一次"在__init__
内,当实例是
创建
decorator = MyDecoratorClass()
第2步:指定要装饰的功能,如果需要,请提供
参数列表,对应于*args
和/或**kwargs
__call__
签名,因为它已在班级中定义。
decorated_fun = decorator(myfun, arg1, arg2)
第3步:最后调用已修饰的函数,如果需要,请提供
函数本身的参数列表,如果提供,则对应于
__call__
函数内部函数的形式参数列表。
如果我理解正确,内部形式参数的名称空间不同于__call__
形式参数的名称空间
decorated_fun(...)
这很有效。但是,如果我想使用我所拥有的缩写符号 写这样的东西:
@MyDecoratorClass(arg1, arg2)
def myfun(*args, **kwargs):
print("myfun was called")
在上面的示例中,我传递了相同的两个位置参数arg1
和arg2
。现在
问题是,这两个参数不是(*args, **kwargs)
指定的
在__call__
中,但实际上是__init__
所以我的问题是,当我们使用缩写表示法来装饰a 通过带有参数的基于类的装饰来运行,如何访问调用 参数列表是为每个装饰函数提供的参数吗?
答案 0 :(得分:1)
这样做......
grails run-app
...不是装饰者的工作方式。装饰器采用单个参数,一个函数,并输出一个函数。
特别是,上述内容并不等同于正确的做法。
C:\grails3projects\pmtracker>grails run-app
| Running application...
ERROR org.springframework.boot.SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean wit
h name 'persistenceInterceptor': Injection of autowired dependencies failed; nes
ted exception is org.springframework.beans.factory.BeanCreationException: Could
not autowire method: public void org.grails.orm.hibernate4.support.AggregatePers
istenceContextInterceptor.setHibernateDatastores(org.grails.orm.hibernate.Abstra
ctHibernateDatastore[]); nested exception is org.springframework.beans.factory.N
oSuchBeanDefinitionException: No qualifying bean of type [org.grails.orm.hiberna
te.AbstractHibernateDatastore] found for dependency [array of org.grails.orm.hib
ernate.AbstractHibernateDatastore]: expected at least 1 bean which qualifies as
autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanP
ostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java
:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb
ject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr
y.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBe
an(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.
preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finish
BeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:538)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationConte
xt.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.
java:766)
at org.springframework.boot.SpringApplication.createAndRefreshContext(Sp
ringApplication.java:361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java
:307)
at grails.boot.GrailsApp.run(GrailsApp.groovy:55)
at grails.boot.GrailsApp.run(GrailsApp.groovy:374)
at grails.boot.GrailsApp.run(GrailsApp.groovy:363)
at grails.boot.GrailsApp$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSi
teArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCa
llSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCa
llSite.java:133)
at pmtracker.Application.main(Application.groovy:8)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not au
towire method: public void org.grails.orm.hibernate4.support.AggregatePersistenc
eContextInterceptor.setHibernateDatastores(org.grails.orm.hibernate.AbstractHibe
rnateDatastore[]); nested exception is org.springframework.beans.factory.NoSuchB
eanDefinitionException: No qualifying bean of type [org.grails.orm.hibernate.Abs
tractHibernateDatastore] found for dependency [array of org.grails.orm.hibernate
.AbstractHibernateDatastore]: expected at least 1 bean which qualifies as autowi
re candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanP
ostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.
java:661)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject
(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanP
ostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java
:331)
... 22 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No q
ualifying bean of type [org.grails.orm.hibernate.AbstractHibernateDatastore] fou
nd for dependency [array of org.grails.orm.hibernate.AbstractHibernateDatastore]
: expected at least 1 bean which qualifies as autowire candidate for this depend
ency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.
raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.
doResolveDependency(DefaultListableBeanFactory.java:1044)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.
resolveDependency(DefaultListableBeanFactory.java:1014)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanP
ostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.
java:618)
... 24 common frames omitted
Picked up _JAVA_OPTIONS: -Xmx512M -Xms512M
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':bootRun'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_31\bin\java.exe'' finished wi
th non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output.
| Error Failed to start server (Use --stacktrace to see the full trace)
decorated_fun = decorator(myfun, arg1, arg2)
@decorator(arg1, arg2)
def myfun(...):
...
# Which is actually equivalent to...
myfun = decorator(arg1, arg2)(myfun)
个参数
如果您想要访问传递给__init__
的参数,可以将它们存储为实例属性。
__call__
虽然,请记住,您不需要使用类装饰器来完成此操作,但以下装饰器将具有相同的行为。
__init__