How do I find out the name of the class used to create an instance of an object in Python?
I'm not sure if I should use the inspect module or parse the __class__ attribute.
Have you tried the __name__ attribute of the class? ie type(x).__name__ will give you the name of the class, which I think is what you want.
>>> import itertools
>>> x = itertools.count(0)
>>> type(x).__name__
'count'
If you're still using Python 2, note that the above method works with new-style classes only (in Python 3+ all classes are "new-style" classes). Your code might use some old-style classes. The following works for both:
x.__class__.__name__
Do you want the name of the class as a string?
instance.__class__.__name__
type() ?
>>> class A:
... def whoami(self):
... print(type(self).__name__)
...
>>>
>>> class B(A):
... pass
...
>>>
>>>
>>> o = B()
>>> o.whoami()
'B'
>>>
class A:
pass
a = A()
str(a.__class__)
The sample code above (when input in the interactive interpreter) will produce '__main__.A' as opposed to 'A' which is produced if the __name__ attribute is invoked. By simply passing the result of A.__class__ to the str constructor the parsing is handled for you. However, you could also use the following code if you want something more explicit.
"{0}.{1}".format(a.__class__.__module__,a.__class__.__name__)
This behavior can be preferable if you have classes with the same name defined in separate modules.
The sample code provided above was tested in Python 2.7.5.
In Python 2,
type(instance).__name__ != instance.__class__.__name__
# if class A is defined like
class A():
...
type(instance) == instance.__class__
# if class A is defined like
class A(object):
...
Example:
>>> class aclass(object):
... pass
...
>>> a = aclass()
>>> type(a)
<class '__main__.aclass'>
>>> a.__class__
<class '__main__.aclass'>
>>>
>>> type(a).__name__
'aclass'
>>>
>>> a.__class__.__name__
'aclass'
>>>
>>> class bclass():
... pass
...
>>> b = bclass()
>>>
>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.bclass at 0xb765047c>
>>> type(b).__name__
'instance'
>>>
>>> b.__class__.__name__
'bclass'
>>>
Alternatively you can use the classmethod decorator:
class A:
#classmethod
def get_classname(cls):
return cls.__name__
def use_classname(self):
return self.get_classname()
Usage:
>>> A.get_classname()
'A'
>>> a = A()
>>> a.get_classname()
'A'
>>> a.use_classname()
'A'
Good question.
Here's a simple example based on GHZ's which might help someone:
>>> class person(object):
def init(self,name):
self.name=name
def info(self)
print "My name is {0}, I am a {1}".format(self.name,self.__class__.__name__)
>>> bob = person(name='Robert')
>>> bob.info()
My name is Robert, I am a person
Apart from grabbing the special __name__ attribute, you might find yourself in need of the qualified name for a given class/function. This is done by grabbing the types __qualname__.
In most cases, these will be exactly the same, but, when dealing with nested classes/methods these differ in the output you get. For example:
class Spam:
def meth(self):
pass
class Bar:
pass
>>> s = Spam()
>>> type(s).__name__
'Spam'
>>> type(s).__qualname__
'Spam'
>>> type(s).Bar.__name__ # type not needed here
'Bar'
>>> type(s).Bar.__qualname__ # type not needed here
'Spam.Bar'
>>> type(s).meth.__name__
'meth'
>>> type(s).meth.__qualname__
'Spam.meth'
Since introspection is what you're after, this is always you might want to consider.
You can simply use __qualname__ which stands for qualified name of a function or class
Example:
>>> class C:
... class D:
... def meth(self):
... pass
...
>>> C.__qualname__
'C'
>>> C.D.__qualname__
'C.D'
>>> C.D.meth.__qualname__
'C.D.meth'
documentation link qualname
To get instance classname:
type(instance).__name__
or
instance.__class__.__name__
both are the same
You can first use type and then str to extract class name from it.
class foo:pass;
bar:foo=foo();
print(str(type(bar))[8:-2][len(str(type(bar).__module__))+1:]);
Result
foo
If you're looking to solve this for a list (or iterable collection) of objects, here's how I would solve:
from operator import attrgetter
# Will use a few data types to show a point
my_list = [1, "2", 3.0, [4], object(), type, None]
# I specifically want to create a generator
my_class_names = list(map(attrgetter("__name__"), map(type, my_list))))
# Result:
['int', 'str', 'float', 'list', 'object', 'type', 'NoneType']
# Alternatively, use a lambda
my_class_names = list(map(lambda x: type(x).__name__, my_list))
Related
I just noticed that
isinstance(myob, MyClass)
does not only return True when myob is an instance of MyClass but also if myob is an instance of a class that inherits from MyClass.
To be more clear, consider the following:
class Book(object):
def __init__(self, cover)
self._cover = cover
class Novel(Book):
def __init__(self, cover, category):
Book.__init__(self, cover)
self._category = category
When instanciating Novel as follows:
novel = Novel('hardcover', 'police')
then
print(isinstance(novel, Book))
and
print (isinstance(novel , Novel))
both print True.
Why is that so? In my sense, novel is a Novel instance, not a Book one...
Also, relevant to this :
In order to get the "grand-mother" (sic) class, I do:
print(novel.__class__.__bases__)
Is there a more direct way?
This transitive behavior is how it should work intuitively ...
>>> class Text:
...: pass
...:
...:
>>> class Book(Text):
...: pass
...:
...:
>>> class Novel(Book):
...: pass
...:
...:
>>> n = Novel()
>>> isinstance(n, Novel)
>>> True
>>> isinstance(n, Book)
>>> True
>>> isinstance(n, Text)
>>> True
... because a Novel is-a Novel, but also is-a Book and is-a Text.
If you want to know whether a class (or instance of a class) is a direct ancestor of another class, you can use the __subclasses__ method of class objects.
>>> Text.__subclasses__()
>>> [__main__.Book]
>>> Book.__subclasses__()
>>> [__main__.Novel]
>>> Novel.__subclasses__()
>>> []
>>>
>>> Novel in Text.__subclasses__()
>>> False
>>> type(n) in Text.__subclasses__()
>>> False
>>> Novel in Book.__subclasses__()
>>> True
>>> type(n) in Book.__subclasses__()
>>> True
edit: YourClass.__bases__ also gives you all direct parent classes.
>>> Novel.__bases__
>>> (__main__.Book,)
Inheritance is "is a" relationship - if Duck inherit from Bird then obviously a duck (instance of Duck) is ALSO a bird (instance of Bird), so the behaviour you observe is really the expected one (and this holds for all class-based OOPLs).
If you want to check the exact type of an object, you can get it using type(obj) - which will return the class of object - and do an identity test against the desired class, ie:
obj = 42
print(type(obj) is int)
I have :
class A:
def a():
pass
After typing in the python command line:
Aobj = A()
aBoundMeth = getattr(Aobj, 'a')
My goal is to get the name of the method that aBoundMeth object represents. Is it possible to do it?
Thank you in advance.
Assuming that the name of the method is the string 'a' (in this case), You can use the __name__ attribute on the function object.
e.g.
>>> Aobj = A()
>>> aBoundMeth = getattr(Aobj, 'a')
>>> aBoundMeth.__name__
'a'
Note that this is the function name when it was created. You can make more references to the same function, but the name doesn't change. e.g.
>>> class A(object):
... def a(self):
... pass
... b = a
...
>>> Aobj = A()
>>> Aobj.a.__name__
'a'
>>> Aobj.b.__name__
'a'
For dictionary we can use .get method. What about a class's attribute and provide a default value?
You can use hasattr and getattr.
For example:
hasattr(foo, 'bar')
would return True if foo has an attribute named bar, otherwise False and
getattr(foo, 'bar', 'quux')
would return foo.bar if it exists, otherwise defaults to quux.
It's dead simple: use a keyword argument.
>>> class Foo(object):
... def __init__(self, my_foo=None):
... self.my_foo = my_foo
...
>>> f = Foo()
>>> f.my_foo
>>> repr(f.my_foo)
'None'
>>> f2 = Foo(2)
>>> f2.my_foo
2
If you are looking for an object which does not have an attribute until you set it, Jason's idea is pretty good unless you directly refer to the attribute. You'll have to work around the AttributeError you'll get. Personally, I'm not a fan of creating objects which must be constantly surrounded by try/except blocks just for the sake of not setting an instance attribute.
Python isn't much for getters and setters. However, you can use property() to work around this problem:
>>> class Foo(object):
... def __init__(self):
... pass
... def get_my_foo(self):
... return getattr(self, "_my_foo", "there's no my_foo")
... def set_my_foo(self, foo):
... self._my_foo = foo
... my_foo = property(get_my_foo, set_my_foo)
...
>>> f = Foo()
>>> f.my_foo
"there's no my_foo"
>>> f.my_foo = "foo!"
>>> f.my_foo
'foo!'
It works just as well to call get_my_foo and set_my_foo, if you like. An added benefit is that you can omit the setter to make a read-only attribute, provided someone using your object doesn't change the underlying _my_foo.
class FooTable(Base):
Id = Column(BIGINT, primary_key=True)
name = Column(VARCHAR(256), nullable=False)
username = Column(VARCHAR(256), nullable=False)
state = Column(VARCHAR(100), nullable=False)
city = Column(VARCHAR(256), nullable=False)
zip = Column(VARCHAR(100), nullable=False)
I want to print out the instantiation arguments of class Column. generally- python code to string. example:
for k, v in vars(FooTable).iteritems():
print k, get_class_attr(v)
>>> Id ["BIGINT", "primary_key=True"]
>>> name ["VARCHAR(256)", "nullable=False"]
...
I tried the inspect module, but found that it does not support it:
http://docs.python.org/library/inspect.html#inspect.getmembers
Thanks for any information
I'd suggest using __dict__ and then filterting its output as dir won't work with metaclasses either.
def filterFunction(field):
'''
This is a sample filtering function
'''
name, value = field
return not name.startswith("_")
for k, v in vars(FooTable).iteritems():
print k, filter(filterFunction, v.__dict__.items())
For that case for the following class
class X():
foo = "bar"
baz = True
Our filter
filter(filterFunction, X.__dict__.items())
would return
[('foo', 'bar'), ('baz', True)]
To get instantiation parameters, i'd check whether field name is in Column.__init__.im_self
Actually what you are asking for, doesn't make much sense. Burhan Khalid's answer is close, but not really. You want the actual arguments that the caller passed when instantiating
the class. Not the function's/constructor's signature.
But this is book keeping that the class' programmer should do on his own. And even then,
he wouldn't actually do that. He would configure each instance based on the passed
parameters.
e.g.
class Foo(object):
def __init__(self, *args, **kwargs):
self.is_cool = kwargs.get('whatever', False)
And then I would check the instance attribute:
f = Foo()
f.is_cool # False
and I would try to make sense of it, depending on what this means for my instance.
But I don't really care about the actual parameters passed. My instance will
configure itself based on what was passed.
You could of course write a class decorator that wraps any 3rd party Class and do
exactly what you need, but it is an overhead that doesn't seem justifiable in this case.
You can print the attributes of a class with:
print dir( Column )
This is if I correctly understand your question
attrs = [i for i in dir(obj) if not i.startswith('_')]
Keep in mind that attributes that begin with _ are generally considered "private". Here is a sample run:
>>> [i for i in dir(4) if not i.startswith('_')]
['conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> [i for i in dir('') if not i.startswith('_')]
['capitalize', 'center', ... 'split', 'splitlines', ... 'upper', 'zfill']
>>> class Foo:
... a = 'Hello'
... def __init__(self):
... pass
... def hello(self):
... print 'Hello'
...
>>> [i for i in dir(Foo) if not i.startswith('_')]
['a', 'hello']
I think you are looking for this:
>>> class Foo:
... def bar(a,b,c):
... pass
...
>>> x = Foo()
>>> x.bar.func_code.co_varnames
('a', 'b', 'c')
Here is another attempt, and I think this does what you need; although its a bit convoluted.
>>> class Foo:
... a = 'b'
... def bar(y,z):
... pass
...
>>> funcs = [(i,getattr(Foo,i).func_code.co_varnames) for i in dir(Foo) \
... if hasattr(getattr(Foo,i),'func_code')]
>>>
>>> funcs
[('bar', ('y', 'z'))]
However if you want to know what arguments were passed to a class, then from the instance, use __dict__.
>>> class Foo:
... a = ''
... def __init__(self, b, c):
... self.a = b
... self.c = c
...
>>> funcs = [(i,getattr(Foo,i).func_code.co_varnames) for i in dir(Foo) if hasattr(getattr(Foo,i),'func_code')]
>>> funcs
[('__init__', ('self', 'b', 'c'))]
>>> i = Foo(1,2)
>>> i.__dict__
{'a': 1, 'c': 2}
I want to know how to use variables for objects and function names in Python. In PHP, you can do this:
$className = "MyClass";
$newObject = new $className();
How do you do this sort of thing in Python? Or, am I totally not appreciating some fundamental difference with Python, and if so, what is it?
Assuming that some_module has a class named "class_name":
import some_module
klass = getattr(some_module, "class_name")
some_object = klass()
I should note that you should be careful here: turning strings into code can be dangerous if the string came from the user, so you should keep security in mind in this situation. :)
One other method (assuming that we still are using "class_name"):
class_lookup = { 'class_name' : class_name }
some_object = class_lookup['class_name']() #call the object once we've pulled it out of the dict
The latter method is probably the most secure way of doing this, so it's probably what you should use if at all possible.
In Python,
className = MyClass
newObject = className()
The first line makes the variable className refer to the same thing as MyClass. Then the next line calls the MyClass constructor through the className variable.
As a concrete example:
>>> className = list
>>> newObject = className()
>>> newObject
[]
(In Python, list is the constructor for the list class.)
The difference is that in PHP, you represent the name of the class you want to refer to as a string, while in Python you can reference the same class directly. If you must use a string (for example if the name of the class is created dynamically), then you will need to use other techniques.
If you need to create a dynamic class in Python (i.e. one whose name is a variable) you can use type() which takes 3 params:
name, bases, attrs
>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})
<class '__main__.MyClass'>
>>> inst = klass()
>>> inst.msg
foobarbaz
Note however, that this does not 'instantiate' the object (i.e. does not call constructors etc. It creates a new(!) class with the same name.
If you have this:
class MyClass:
def __init__(self):
print "MyClass"
Then you usually do this:
>>> x = MyClass()
MyClass
But you could also do this, which is what I think you're asking:
>>> a = "MyClass"
>>> y = eval(a)()
MyClass
But, be very careful about where you get the string that you use "eval()" on -- if it's come from the user, you're essentially creating an enormous security hole.
Update: Using type() as shown in coleifer's answer is far superior to this solution.
I use:
newObject = globals()[className]()
I prefer using dictionary to store the class to string mapping.
>>> class AB:
... def __init__(self, tt):
... print(tt, "from class AB")
...
>>> class BC:
... def __init__(self, tt):
... print(tt, "from class BC")
...
>>> x = { "ab": AB, "bc": BC}
>>> x
{'ab': <class '__main__.AB'>, 'bc': <class '__main__.BC'>}
>>>
>>> x['ab']('hello')
hello from class AB
<__main__.AB object at 0x10dd14b20>
>>> x['bc']('hello')
hello from class BC
<__main__.BC object at 0x10eb33dc0>