开发者

How do I get the concrete name (e.g. "<module_name>"."<class_name">) of a class reference in Python?

开发者 https://www.devze.com 2023-01-08 11:28 出处:网络
This is what I have so far: def get_concrete_name_of_class(klass): \"\"\"Given a class return the concrete name of the class.

This is what I have so far:

def get_concrete_name_of_class(klass):
"""Given a class return the concrete name of the class.

klass - The reference to the class we're interested in.
"""

# TODO: How do I check that klass is actually a class?
# even better would be determine if it's old style vs new style
# at the same time and handle things differently below.

# The str of a newstyle class is "<class 'django.forms.CharField'>"
# so we search for the single quotes, and grab everything inside it,
# giving us "django.forms.CharField"
matches = re.search(r"'(.+)'", str(klass))
if matches:
    return matches.group(1)

# Old style's classes' str is the concrete class name.
return str(klass)

So this works just fine, but it seems pretty hackish to have to do a regex search on the string of the class. Note that I cannot just do klass().__class__.__name__ (can't deal with args, etc.).

Also, does anyone know how to accomplish the TODO (check if klass is a class and whether its oldstyle vs new style)?

Any suggestions would be greatly appreciated.

Based on the comments here's what I ended up with:

def get_concrete_name_of_class(klass):
    """Given a class return the concrete name of the class.

    klass - The reference to the class we're interested in.

    Raises a `TypeError` if klass is not a class.
    """

    if not isinstance(klass, (type, ClassType)):
        raise TypeError('The klass a开发者_JS百科rgument must be a class. Got type %s; %s' % (type(klass), klass))

    return '%s.%s' % (klass.__module__, klass.__name__)


How about just using klass.__name__, or to get the fully qualified name, klass.__module__+'.'+klass.__name__?


You can just say

klass.__module__ + "." + klass.__name__

As for how to determine whether something is an old class or new class, I recommend saying something like

from types import ClassType  # old style class type

if not isinstance(klass, (type, ClassType)):
    # not a class
elif isinstance(klass, type):
    # new-style class
else:
    # old-style class


>>> class X:
...     pass
... 
>>> class Y( object ):
...     pass
... 

The type function tells you if a name is a class and old-style vs. new style.

>>> type(X)
<type 'classobj'>
>>> type(Y)
<type 'type'>

It also tells you what an object is.

>>> x= X()
>>> type(x)
<type 'instance'>
>>> y= Y()
>>> type(y)
<class '__main__.Y'>

You can test old-stye vs. new style by simply asking what it's a subclass of.

>>> issubclass(y.__class__,object)
True
>>> issubclass(x.__class__,object)
False
>>> 
0

精彩评论

暂无评论...
验证码 换一张
取 消