Is thre a better way to build it so it print all attributes from class/parent-class
<p>I have a <code>Student</code> class extending <code>Person</code> class, both class implemented <code>__str__</code> to list out all attributes in both <code>Person</code> and <code>Student</code> class. </p>

<p>However, I am having issues with trying to do a print of <code>__str__</code> in the <code>__init__</code> function as below. </p>

<pre><code>class Person(object):
    def __init__(self, n):
        self.name = n
        print Person.__str__(self)

    def __str__(self):
        return "%15s%s\n" % ("Name: ", self.name)

class Student(Person):
    def __init__(self, n, sid, d):
        Person.__init__(self,n)
        self.sid = sid
        self.degree = d
        print Student.__str__(self)

    def __str__(self):
        return Person.__str__(self) + "%15s%s\n%15s%s\n"  % ("StudentID: ", self.sid, "Degree: ", self.degree)
</code></pre>

<p>When I execute the following</p>

<pre><code>Jeff = Person("Jeff")
Cameron = Student('Cameron', 'U2314313', "Social Science")
</code></pre>

<p>it would produce something like:</p>

<pre><code>Name: Jeff
Name: Cameron
Name: Cameron
StudentID:......
Degree:......
</code></pre>

<p>When initializing <code>Student</code>, it's calling <code>Student.__str__(self)</code>, and subsequently call <code>Person.__str__(self)</code> in order to bring back the name. </p>

<p>Just wondering if there's a better way to build the the structure so it's more usable and inline with the OO concept. </p>

<p>The result that I want is when I do the <code>__str__</code> for both <code>Student</code> or <code>Person</code>, it would list out all attributes, such as:</p>

<pre><code>Name: Jeff
Name: Cameron
StudentID:......
Degree:......
</code></pre>

<p>and when I do something like <code>print Cameron</code>, it would still give me </p>

<pre><code>Name: Cameron
StudentID:......
Degree:......
</code></pre>

<p>I know my code is duplicating it at the moment, but I can't figure out a way to make it work the way I intended... Help please. </p>

<p>You may use the <code>getmembers</code> function of <a href="https://docs.python.org/3/library/inspect.html#inspect.getmembers" rel="nofollow"><code>inspect</code></a> module to get the all the members of the class dynamically. </p>

<p>Generic function to <code>return</code> attributes based on passed <code>class</code> or <code>class's object</code> can be define as:</p>

<pre><code>import inspect

def get_attributes(class_object):
    attributes = inspect.getmembers(class_object, lambda a:not(inspect.isroutine(a)))
    return [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))] 
</code></pre>

<p>Now the demonstration, on HOW this will work:</p>

<pre><code># Parent class
class MyClass(object):
    a = '12'
    b = '34'

# Child class
class MyChildClass(MyClass):
    c = '20'
    def __init__(self):
        self.x = 20

get_attributes(MyClass)  &lt;-- Parent Class
# returns: [('a', '12'), ('b', '34')]
# Return all the class attributes of "MyClass"

get_attributes(MyChildClass)  &lt;-- Child Class
# returns: [('a', '12'), ('b', '34'), ('c', '20')]
# Returns all the class attributes of "MyChildClass"

get_attributes(MyChildClass())  &lt;-- Object Of Child Class
# returns: [('a', '12'), ('b', '34'), ('c', '20'), ('x', 20)]
# Returns all the class + object attributes of "MyChildClass's object" 
</code></pre>

python class oop initialization