Python Functions Can Have Attributes? -
i'm new python , don't understand how functions can seemingly have attributes. in code below, there function called f, , later in code, name of f.count referenced. how can function, namely f, have .count? i'm getting error message of: 'nonetype' object has no attribute 'count' on line, doesn't have attribute yet. how give attribute?
def fcount(n): print n.__name__ @fcount def f(n): return n+2 n in range(5): print n #print f(n) print 'f count =',f.count #the line causing error mentioned above @fcount def g(n): return n*n print 'g count =',g.count print g(3) print 'g count =',g.count edit: added fcount(), doesn't much, , details error.
let’s start definition of f:
@fcount def f(n): return n+2 this defines f return value of call function fcount, used decorator (the leading @) here.
this code equivalent with
def f(n): return n+2 f = fcount(f) since decorator – fcount – not return anything, f none and not function @ call site.
in case fcount should return function , add count attribute returned function. useful (?) might be
def fcount(fn): def wrapper(n): wrapper.count += 1 return fn(n) wrapper.count = 0 return wrapper edit
as @jonrsharpe pointed out, generalized decorator can forward positional , keyword arguments capturing them *args , **kwargs in signature , expanding them in same way when calling function. names args , kwargs used convention.
python has helper function (a decorator itself) can transfer information (name, docstring , signature information) 1 function another: functools.wraps. complete example looks this:
from functools import wraps def decorator(func): @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper @decorator def f(a, b, c=none): "the useful f function" pass print f.__name__ # `f` rather `wrapper` print help(f) # `f(*args, **kwargs) useful f function` rather `wrapper(*args, **kwargs)`
Comments
Post a Comment