Bottom Page

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
 Mix-in class tree file not running the self test code.
#1
Hi,
I am learning Python classes and I have hit a roadblock in one particular file. So, I coded a file(listtree.py) which has a self-test code with a module listed below(testmixin.py). When I am running listtree.py, I am getting an error which I cannot understand(listed below). Please let me know if anyone can help me out on this. Have been staring at it for an hour but no luck. Wall

-Arjun


#!python
# File: listtree.py (2.X + 3.X)


class ListTree:
    """
    Mix-in that returns an __str__ trace of the entire class tree and all
    its objects' attrs at and above self; run by print(), str() returns
    constructed string; uses __X attr names to avoid impacting clients;
    recurses to superclasses explicitly, uses str.format()for clarity;
    """

    def __attrnames(self, obj, indent):
        spaces = ' ' * (indent+ 1)
        result = ''
        for attr in sorted(obj.__dict__):
            if attr.startswith('__') and attr.endswith('__'):
                result += spaces + '{0}\n'.format(attr)
            else:
                result += spaces + '{0}={1}\n'.format(attr, getattr(obj, attr))
        return result


    def __listclass(self, aClass, indent):
        dots = '.' * indent
        if aClass in self.__visited:
            return '\n{0}<Class {1}:, address {2}: (see above)>\n'.format(
                            dots,
                            aClass.__name__,
                            id(aClass))
        
        else:
            self.__visited[aClass] = True
            here  = self.__attrnames(aClass, indent)
            above = ''
            for super in aClass.__bases__:
                above += self.__listclass(super, indent+4)
            return '\n{0}<Class {1}, address {2}: \n{3}{4}{5}>\n'.format(
                            dots,
                            aClass.__name__,
                            id(aClass),
                            here, above,
                            dots)


    def __str__(self):
        self.__visited = {}
        here  = self.__attrnames(self, 0)
        above = self.__listclass(self.__class__, 4)
        return '<Instance of {0}, address {1}:\n{2]{3}>'.format(
                            self.__class.__name__,
                            id(self),
                            here, above)


if __name__ == '__main__':
    import testmixin
    testmixin.tester(ListTree)

                    
#!python
# File: testmixin.py (2.X + 3.X)

"""
Generic lister mixin tester: similar to transitive reloader in
Chapter 25, but passes a class object to tester (not function),
and testbyNames adds loading of both module and class by name
string here, in keeping with Chapter 31's factory pattern.
"""

import importlib



def tester(listerclass, sept=False):
    


    class Super:
        def __init__(self):                             # Superclass __init__
            self.data1 = 'spam'                         # Create instance attrs
        def ham(self):
            pass


    class Sub(Super, listerclass):                      # Mix in ham and a __str__
        def __init__(self):                             # Listers have access to self
            Super.__init__(self)
            self.data2 = 'eggs'                         # More instance attrs
            self.data3 = 42
        def spam(self):                                 # Define another method here
            pass


    instance = Sub()                                    # Return instance with lister's __str__
    print(instance)                                     # Run mixed-in __str__ (or via str(x))
    if sept:
        print('-' * 80)



def testbyNames(modname, classname, sept=False):
    modobject   = importlib.import_module(modname)      # Import by namestring
    listerclass = getattr(modobject, classname)         # Fetch attr by name string
    tester(listerclass, sept)



if __name__ == '__main__':
    testbyNames('listtree', 'ListTree', False)

Error:
Traceback (most recent call last): File "C:\Users\Ganga Mohan\AppData\Local\Programs\Python\Python36-32\listtree.py", line 58, in <module> testmixin.tester(ListTree) File "C:\Users\Ganga Mohan\AppData\Local\Programs\Python\Python36-32\testmixin.py", line 36, in tester print(instance) # Run mixed-in __str__ (or via str(x)) File "C:\Users\Ganga Mohan\AppData\Local\Programs\Python\Python36-32\listtree.py", line 51, in __str__ self.__class.__name__, AttributeError: 'Sub' object has no attribute '_ListTree__class'
Quote
#2
Howdy Arjun!
On line 51 of your listtree.py file you have a typo. self.__class.__name__,
Should instead be self.__class__.__name__,

The error message alerts you of this by saying AttributeError: 'Sub' object has no attribute '_ListTree__class'



Without the trailing '__' on __class__ python 'mangles' the method call for self.__class to make it call a private method 'self._ListTree__class'
'self' in this case is the Sub class from testmixin.py the interpreter throws the error before moving to the .__name__ portion of your code on line 51.



Hope this helped sort your problem.

-Retrubtion
Quote
#3
Aaaaarrrrggg....That was stupid, it sort of camouflaged and being a beginner I couldn't spot it...Dammnn..

Thank you so much man, this really helps me move past it...really appreciate it...

-Arjun
Quote
#4
Hey Retribution,

Sorry to bug you again but, I corrected the line 51 to self.__class__.__name__.
Unfortunately I am getting a subsequent error which is as follows;
Please let me know where did I screw up this time.

#!python
# File: listtree.py (2.X + 3.X)


class ListTree:
    """
    Mix-in that returns an __str__ trace of the entire class tree and all
    its objects' attrs at and above self; run by print(), str() returns
    constructed string; uses __X attr names to avoid impacting clients;
    recurses to superclasses explicitly, uses str.format()for clarity;
    """

    def __attrnames(self, obj, indent):
        spaces = ' ' * (indent+ 1)
        result = ''
        for attr in sorted(obj.__dict__):
            if attr.startswith('__') and attr.endswith('__'):
                result += spaces + '{0}\n'.format(attr)
            else:
                result += spaces + '{0}={1}\n'.format(attr, getattr(obj, attr))
                #result += spaces + '%s=%s\n' % (attr, getattr(obj, attr))
        return result


    def __listclass(self, aClass, indent):
        dots = '.' * indent
        if aClass in self.__visited:
            return '\n{0}<Class {1}:, address {2}: (see above)>\n'.format(
                            dots,
                            aClass.__name__,
                            id(aClass))
        
        else:
            self.__visited[aClass] = True
            here  = self.__attrnames(aClass, indent)
            above = ''
            for super in aClass.__bases__:
                above += self.__listclass(super, indent+4)
            return '\n{0}<Class {1}, address {2}: \n{3}{4}{5}>\n'.format(
                            dots,
                            aClass.__name__,
                            id(aClass),
                            here, above,
                            dots)


    def __str__(self):
        self.__visited = {}
        here  = self.__attrnames(self, 0)
        above = self.__listclass(self.__class__, 4)
        return '<Instance of {0}, address {1}:\n{2]{3}>'.format(
                            self.__class__.__name__,
                            id(self),
                            here, above)


if __name__ == '__main__':
    import testmixin
    testmixin.tester(ListTree)

                    
#!python
# File: testmixin.py (2.X + 3.X)

"""
Generic lister mixin tester: similar to transitive reloader in
Chapter 25, but passes a class object to tester (not function),
and testbyNames adds loading of both module and class by name
string here, in keeping with Chapter 31's factory pattern.
"""

import importlib



def tester(listerclass, sept=False):
    


    class Super:
        def __init__(self):                             # Superclass __init__
            self.data1 = 'spam'                         # Create instance attrs
        def ham(self):
            pass


    class Sub(Super, listerclass):                      # Mix in ham and a __str__
        def __init__(self):                             # Listers have access to self
            Super.__init__(self)
            self.data2 = 'eggs'                         # More instance attrs
            self.data3 = 42
        def spam(self):                                 # Define another method here
            pass


    instance = Sub()                                    # Return instance with lister's __str__
    print(instance)                                     # Run mixed-in __str__ (or via str(x))
    if sept:
        print('-' * 80)



def testbyNames(modname, classname, sept=False):
    modobject   = importlib.import_module(modname)      # Import by namestring
    listerclass = getattr(modobject, classname)         # Fetch attr by name string
    tester(listerclass, sept)



if __name__ == '__main__':
    testbyNames('listinstance', 'ListInstance', True)   # Test all three here
    testbyNames('listinherited', 'ListInherited', True)
    testbyNames('listtree', 'ListTree', False)
    
Error:
Traceback (most recent call last): File "C:\Users\Ganga Mohan\AppData\Local\Programs\Python\Python36-32\listtree.py", line 59, in <module> testmixin.tester(ListTree) File "C:\Users\Ganga Mohan\AppData\Local\Programs\Python\Python36-32\testmixin.py", line 36, in tester print(instance) # Run mixed-in __str__ (or via str(x)) File "C:\Users\Ganga Mohan\AppData\Local\Programs\Python\Python36-32\listtree.py", line 54, in __str__ here, above) ValueError: unexpected '{' in field name
Quote

Top Page

Possibly Related Threads...
Thread Author Replies Views Last Post
  Running tests in a sibling directory to code sodhiar 1 114 Nov-07-2019, 11:28 PM
Last Post: MckJohan
  NameError: name 'display' is not defined when running code on power bi beginner1 2 1,305 Jul-24-2019, 11:03 AM
Last Post: beginner1
  Interpreter and running a .py file give different outputs PythonNPC 5 302 Jul-21-2019, 01:07 PM
Last Post: PythonNPC
  How to save a class object to a file? SheeppOSU 2 252 Jun-22-2019, 11:54 PM
Last Post: metulburr
  Batch file not running python script in task scheduler davork 3 720 May-09-2019, 12:53 PM
Last Post: Gribouillis
  Syntax Error when running code codeman 3 511 Apr-02-2019, 11:47 AM
Last Post: codeman
  Running python code meant for Notepad++ plugin independently greektranslator 3 396 Jan-28-2019, 06:03 PM
Last Post: maxtimbo
  code keeps running if i use from threading import timer? birddseedd 3 378 Jan-25-2019, 05:00 AM
Last Post: stullis
  Python unittest - running multiple tests from CSV file asheru93 0 489 Jan-21-2019, 08:26 AM
Last Post: asheru93
  Problems running exe file from pyinstaller ersa21 4 766 Jan-15-2019, 06:36 PM
Last Post: snippsat

Forum Jump:


Users browsing this thread: 1 Guest(s)