[Python-ideas] Proposal for new-style decorators

Mathias Panzenböck grosser.meister.morti at gmx.net
Fri Apr 29 19:03:49 CEST 2011


Maybe even better, decorator and simple_decorator in one:


def decorator(deco):
	"""deco(func,func_args,func_kwargs,deco_args...)
	
	@decorator
	def my_deco(func,func_args,func_kwargs,deco_args...):
		pass
	
	@my_deco(*deco_args,**deco_kwargs)
	def func(*func_args,**func_kwargs):
		pass
		
	@decorator
	def my_deco2(func,func_args,func_kwargs):
		pass
		
	@my_deco2
	def func2(*func_args,**func_kwargs):
		pass

	@decorator
	def my_deco3(func,func_args,func_kwargs,x=1):
		pass
		
	@my_deco3()
	def func3(*func_args,**func_kwargs):
		pass
	"""
	arg_names, flags, defaults, deco_name = inspect_callable(deco)
	if flags & FUNC_ARGS == 0:
		if len(arg_names) < 3:
			raise TypeError('decorator functions need at least 3 ' +
				'arguments (func, func_args, func_kwargs)')
		del arg_names[0:3]
	if not arg_names and flags & (FUNC_ARGS | FUNC_KWARGS) == 0:
		# argument-less decorator
		del arg_names, flags, defaults, deco_name
		@wraps(deco)
		def _deco(func):
			apply_func_args = args_applyer(*inspect_callable(func))
			@wraps(func)
			def _f(*args,**kwargs):
				return deco(func,*apply_func_args(*args,**kwargs))
			return _f
		return _deco
	else:
		apply_deco_args = args_applyer(arg_names,flags,defaults,deco_name)
		del arg_names, flags, defaults, deco_name
		@wraps(deco)
		def _deco_deco(*deco_args,**deco_kwargs):
			deco_args, deco_kwargs = apply_deco_args(*deco_args, **deco_kwargs)
			def _deco(func):
				apply_func_args = args_applyer(*inspect_callable(func))
				@wraps(func)
				def _f(*func_args,**func_kwargs):
					func_args, func_kwargs = apply_func_args(
						*func_args, **func_kwargs)
					return deco(func,func_args,func_kwargs,
						*deco_args,**deco_kwargs)
				return _f
			return _deco
		return _deco_deco



More information about the Python-ideas mailing list