Python: __qualname__ of function with decorator
name of module in which this class was defined,name of module in which this method was defined,name of module in which this function was defined,name with which this class was defined
def gen(): yield @types.coroutine def gen_coro(): yield assert not isawaitable(gen()) assert isawaitable(gen_coro())
This comes down to the fact that qualname uses the line number attribute of the code attribute of the function, and functools,wraps doesn't change the code object
import functools from qualname import qualname def decorator(f): @functools.wraps(f) def wrapper( * args, ** kwargs): return f( * args, ** kwargs) return wrapper @decorator def h(): pass print(qualname(h)) print(h.__qualname__)
functools is a standard Python module for higher-order functions (functions that act on or return other functions), wraps() is a decorator that is applied to the wrapper function of a decorator
wrapper A wrapper function wrapper A wrapper function
def my_function(): pass class MyClass(object): def method(self): pass print(my_function.__name__) # gives "my_function" print(MyClass.method.__name__) # gives "method" print(my_function.__qualname__) # gives "my_function" print(MyClass.method.__qualname__) # gives "MyClass.method"
Administration User List Committer List , Summaries Issues with patch Easy issues Stats
Python 3 introduced __qualname__. This attribute exists on class types and also instances of certain class types, such as functions. For example: def f(): pass print(f.__name__) print(f.__qualname__) class Class: pass print(Class.__name__) print(Class.__qualname__) yields: f f Class Class An instance of a class however does not have __name__ or __qualname__ attributes. With: c = Class() print(c.__name__) print(c.__qualname__) yielding: Traceback (most recent call last): File "qualnametest.py", line 13, in <module> print(c.__name__) AttributeError: 'Class' object has no attribute '__name__' Traceback (most recent call last): File "qualnametest.py", line 14, in <module> print(c.__qualname__) AttributeError: 'Class' object has no attribute '__qualname__' For a class, it is possible to override the __name__ attribute using a property. class Class: @property def __name__(self): return 'override' c = Class() print(c.__name__) With the result being: override This is useful in writing object proxies or function wrappers for decorators as rather than having to copy the __name__ attribute into the wrapper, the lookup can be deferred until when it is required. The same though cannot be done for __qualname__. With: class Class: @property def __qualname__(self): return 'override' yielding an error when the class definition is being processed: Traceback (most recent call last): File "qualnametest.py", line 16, in <module> class Class: TypeError: type __qualname__ must be a str, not property This means the same trick cannot be used in object proxies and function wrappers and instead __qualname__ must be copied and assigned explicitly as a string attribute in the __init__() function of the object proxy or function wrapper. I can sort of understand a prohibition on __qualname__ being a string attribute in certain cases, especially if overriding it on a type or instance where __qualname__ attribute already exists, but I don't understand why a limitation would be imposed to prevent using a property as a means of generating the value for a class instance which doesn't otherwise have a __qualname__ attribute. There is no similar restriction for __name__. Unless there is a good specific reason for this behaviour, the ability to override it with a property in cases where the __qualname__ attribute didn't already exist, would be handy for proxies and wrappers.
I'm using a Decorator (class) in an Instance method of another class, like this:,Now, when I print out self,sayHello
class decorator_with_arguments(object): def __init__(self, arg1 = 0, arg2 = 0, arg3 = 0): self.arg1 = arg1 self.arg2 = arg2 self.arg3 = arg3 def __call__(self, f): print("Inside __call__()") def wrapped_f( * args): print(f.__qualname__) f( * args) return wrapped_f class Lol: @decorator_with_arguments("hello") def sayHello(self, a1, a2, a3, a4): print(self.sayHello.__qualname__)
You can simply copy the __qualname__ attribute across to your wrapped_f wrapper function; it is this function that is returned when the decorator is applied, after all,,The @wraps(f) decorator there copies the relevant attributes from f onto wrapped_f, including __qualname__:,You could use the @functools
from functools import wraps class decorator_with_arguments(object): def __init__(self, arg1 = 0, arg2 = 0, arg3 = 0): self.arg1 = arg1 self.arg2 = arg2 self.arg3 = arg3 def __call__(self, f): print("Inside __call__()") @wraps(f) def wrapped_f( * args): print(f.__qualname__) f( * args) return wrapped_f
Other "python-qualname" answers related to "Python: __qualname__ of function with decorator"
- Creating a drop-down menu of Member IDs
- How to remove an item from a dictionary that is iterated?
- Return price as an object/variable using Interactive Brokers TWS API - Python
- For loop is not working while appending rows
- Python help to debug an error when modify a file in a stream mode
- Mido - How to get midi data in realtime from different ports
- Using Java's ByteBuffer to replicate Python's struct.pack
- CreateConsoleScreenBuffer in Python
- QOpenGLWidget only updates when resized
- Python requests 'certificate verify failed' for a specific SNI certificate
- Django ORM's contains vs SQL's LIKE
- Module 'tensorflow' has no attribute 'random'
- Redirection using WSGIref
- Pygame Mixer module not available [duplicate]
- How do I see and customize the source code to Python's defined functions; describe, skew, and kurtosis definitions?
- Delaying parts of text being inserted into Scroll Text Box (scrolledtext)
- Dataflow GCS to BigQuery - How to output multiple rows per input?
- Identify Format of date in python
- Sklearn - Return top 3 classes from Logistic Regression
- Smoothing of graph gives a huge difference in the range