Try the inspect module. getmembers and the various tests should be helpful.
EDIT:
For example,
class MyClass(object):
a = '12'
b = '34'
def myfunc(self):
return self.a
>>> import inspect
>>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
[('__class__', type),
('__dict__',
<dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
'a': '34',
'b': '12',
'myfunc': <function __main__.myfunc>}>),
('__doc__', None),
('__module__', '__main__'),
('__weakref__', <attribute '__weakref__' of 'MyClass' objects>),
('a', '34'),
('b', '12')]
Now, the special methods and attributes get on my nerves- those can be dealt with in a number of ways, the easiest of which is just to filter based on name.
>>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
>>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
[('a', '34'), ('b', '12')]
...and the more complicated of which can include special attribute name checks or even metaclasses ;)
Answer from Matt Luongo on Stack OverflowTry the inspect module. getmembers and the various tests should be helpful.
EDIT:
For example,
class MyClass(object):
a = '12'
b = '34'
def myfunc(self):
return self.a
>>> import inspect
>>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
[('__class__', type),
('__dict__',
<dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
'a': '34',
'b': '12',
'myfunc': <function __main__.myfunc>}>),
('__doc__', None),
('__module__', '__main__'),
('__weakref__', <attribute '__weakref__' of 'MyClass' objects>),
('a', '34'),
('b', '12')]
Now, the special methods and attributes get on my nerves- those can be dealt with in a number of ways, the easiest of which is just to filter based on name.
>>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
>>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
[('a', '34'), ('b', '12')]
...and the more complicated of which can include special attribute name checks or even metaclasses ;)
def props(cls):
return [i for i in cls.__dict__.keys() if i[:1] != '_']
properties = props(MyClass)
No because the attributes are dynamic (so called instance attributes). Consider the following,
class Foo:
def __init__( self ):
self.bar = 1
def twice( self ):
self.barbar = 2
f = Foo()
print( list(f.__dict__.keys() ) )
f.twice()
print( list(f.__dict__.keys() ) )
In the first print, only f.bar was set, so that's the only attributes that's shown when printing the attribute keys. But after calling f.twice(), you create a new attribute to f and now printing it show both bar and barbar.
Warning -
The following isn't foolproof in always providing 100% correct data. If you end up having something like self.y = int(1) in your __init__, you will end up including the int in your collection of attributes, which is not a wanted result for your goals. Furthermore, if you happen to add a dynamic attribute somewhere in your code like Foo.some_attr = 'pork', then you will never see that either. Be aware of what it is that you are inspecting at what point of your code, and understand why you have and don't have those inclusions in your result. There are probably other "breakages" that will not give you the full 100% expectation of what are all the attributes associated with this class, but nonetheless, the following should give you something that you might be looking for.
However, I strongly suggest you take the advice of the other answers here and the duplicate that was flagged that explains why you can't/should not do this.
The following is a form of solution you can try to mess around with:
I will expand on the inspect answer.
However, I do question (and probably would advice against) the validity of doing something like this in production-ready code. For investigative purposes, sure, knock yourself out.
By using the inspect module as indicated already in one of the other answers, you can use the getmembers method which you can then iterate through the attributes and inspect the appropriate data you wish to investigate.
For example, you are questioning the dynamic attributes in the __init__
Therefore, we can take this example to illustrate:
from inspect import getmembers
class Foo:
def __init__(self, x):
self.x = x
self.y = 1
self.z = 'chicken'
members = getmembers(Foo)
for member in members:
if '__init__' in member:
print(member[1].__code__.co_names)
Your output will be a tuple:
('x', 'y', 'z')
Ultimately, as you inspect the class Foo to get its members, there are attributes you can further investigate as you iterate each member. Each member has attributes to further inspect, and so on. For this particular example, we focus on __init__ and inspect the __code__ (per documentation: The __code__ object representing the compiled function body) attribute which has an attribute called co_names which provides a tuple of members as indicated above with the output of running the code.
python - Is there any way to get class instance attributes without creating class instance? - Stack Overflow
python - Get class and object attributes of class without methods and builtins - Stack Overflow
object oriented - Why access the attributes of a Python class by reference? - Software Engineering Stack Exchange
using an attribute from a class in python without creating an object - Stack Overflow
Videos
If you insist on using an overly general dictionary to initialize your object, just define __init__ to accept, but ignore, the extra keys.
class MyClass(object):
def __init__(self, attr1, attr2, **kwargs):
self.attr1 = attr1
self.attr2 = attr2
d = {'attr1': 'value1', 'attr2': 'value2', 'extra_key': 'value3'}
new_instance = MyClass(**d)
If you can't modify __init__ (as appears to be the case if it inherits from a SQLAlchemy declarative base), add an alternate constructor to accept all the keyword arguments but pick out the ones you need.
class MyClass(Base):
@classmethod
def from_dict(cls, **kwargs):
# Let any KeyErrors propagate back to the caller.
# They're the one who forgot to make sure **kwargs
# contained the right keys.
value1 = kwargs['attr1']
value2 = kwargs['attr2']
return cls(value1, value2)
new_instance = MyClass.from_dict(**d)
Disclaimer: This answers what OP was asking about (getting attributes of an instance), not what they needed. Which seems to be constructor's parameter list.
You cannot do what you want. In python attributes are added to an instance of a class dynamically. Two instances of the same class can have different attributes. Well... to be precise, there are things called instance attributes, and class attributes.
Instance attributes are the ones associated with the instance of a class. Class attributes are associated with its definition i.e. if you wrote (MyClass.foo)
If you look at the example, the attributes are added during the __init__ on self so they are instance attributes.
What you could do is to create a valid instance and inspect it (look at below example), provide a static list of allowed_keys (e.g. as a class attribute), or in some way require allowed_keys as constructor parameter. All of these are kind of workarounds as what you really need is impossible. They have their pros and cons.
example:
class MyClass(object):
def __init__(self, value1, value2):
self.attr1 = value1
self.attr2 = value2
instance = MyClass(1,2) # create a valid object
instance_attributes = instance.__dict__.keys() # inspect it
print(instance_attributes)
You can filter out everything you don't need from __dict__:
def getAttributes(clazz):
return {name: attr for name, attr in clazz.__dict__.items()
if not name.startswith("__")
and not callable(attr)
and not type(attr) is staticmethod}
Edit: An alternative that behaves slightly differently for class properties and descriptors:
def getAttributes2(clazz):
attrs = {}
for name in vars(clazz):
if name.startswith("__"):
continue
attr = getattr(clazz, name)
if callable(attr):
continue
attrs[name] = attr
return attrs
(In practice, this should be rarely different from the first version.)
This should get you close:
import inspect
class MyClass(object):
my_attrib = 'foo'
my_other_attrib = 'bar'
def mymethod():
pass
for name, value in inspect.getmembers(MyClass):
if not inspect.ismethod(value) and not name.startswith('__'):
print name
This outputs:
my_attrib
my_other_attrib
NOTE - There may be a better / more-official way to do this, but this should point you in the right direction.
That reference isn't describing a special case of the language rules, it's a natural result of everything being an object.
The special case is that MyClass(args...) is wired up to create a new object and call MyClass.__init__ (among other things).
It allows you to change the state of the class after it is defined. This can be as simple as changing "static" data based on some configuration.
class EggsApiClient:
default_url = "example.com"
def connect(self):
# do stuff with default_url
if __name__ = "main":
EggsApiClient.default_url = parse_args("default_url")
This is not something that I think most Python users will ever need to do and almost surely shouldn't but it does have a distinct purpose and it's worth understanding.
Consider the following example:
class Foo:
def set_a(self, a):
self.a = a
class Bar:
def set_b(self, b):
self.b = b
foo = Foo()
foo.set_a(1)
print(foo.a)
bar = Bar()
# interesting part here!
Foo.set_a(bar, 2)
print(bar.a)
Through this feature, we have effectively called set_a on a Bar instance, despite the fact that Bar doesn't have a set_a method defined. That is, if we try:
bar.set_a()
We get an error: AttributeError: 'Bar' object has no attribute 'set_a'.
You might (quite reasonably) ask, "OK, but why would I do that?" Personally, I think I did something like this many moons ago but there was probably a simpler solution to whatever I was trying to accomplish.
I can imagine this be useful in various frameworks e.g. something like unit testing. But the main reason I think you might end up doing this is when you are using a more functional style. For example, you might have a function like this which has no knowledge of Foo or Bar:
def apply(obj, func, *params):
func(obj, *params)
Which you can then call like so:
apply(bar, Bar.set_b, 3)
print(bar.b)
A real example of the kind of thing you might actually do:
class Person:
def __init__(self, name: str, student: bool):
self.name = name
self.student = student
def is_student(self):
return self.student
def __repr__(self):
return f"{self.name} - student: {self.student}"
people = [Person("bob", False), Person("alice", True), Person("carl", True)]
def display(iter):
print("---")
for i in iter:
print(i)
display(people)
display(filter(Person.is_student, people))
Or maybe something like this:
people = map(Person, ["dave", "edith", "frank"], [True, False, True])
display(people)
Check out the functools module for more interesting functional-style approaches like this.
The simplest way:
In [12]: class MyClass(object):
...: attr = 'attr value'
In [15]: MyClass.attr
Out[15]: 'attr value'
You can use __dict__ attribute also:
__dict__ is the dictionary containing the class's namespace.
In [15]: MyClass.__dict__.get('attr', None)
Out[15]: 'attr value'
Use staticmethod decorator if you need to use a method:
In [12]: class MyClass(object):
...: @staticmethod
...: def the_static_method(x):
...: print(x)
In [15]: MyClass.the_static_method(2)
Out[15]: 2
There really is no reason to create a new object in other to utilize the properties and methods of another object.
You only want to create an instance of Class_A in File_B to use it's properties and methods.
For example:
import Class_A
#instance of Class_A
classA = Class_A('params')
#property1 is a property in classA
classA.property1
#doSomething is a method in classA
classA.doSomething()
Read more about OOP here http://www.python-course.eu/object_oriented_programming.php
I've had a lot of issues getting information into and out of a list of classes that I've generated by iteration. In my latest project, I'm using PDF2image to open a pdf and store each page in a list of classes as well as a few other attributes unique to each page. My problem is that I have a really loose grip on how to handle data coming in and out of functions and particularly classes. Like in the following:
'class page():
def __init__(self, image, other_stuff)
Self. Image = image
Self. Other_stuff = otherPage_list = []
def pdfloader():
Pages = convert_from_bytes(path)
For page in pages:
Page_list.append(page(image = page, other_stuff = None))'
So like, in this example, I've appended 'page_list' with a new instance for each page that was pulled from the pdf and stored as an array. This works great. But now I have no idea how to access each instance to get the array, and then write 'other_stuff' to that instance.
(Also, sorry for the formatting, I'm writing this on mobile and I have to be in bed for work tomorrow. If it makes no sense, I'll take it down and re-post when I get the chance on desktop)