Why can't I iterate over an object that delegates via __getattr__ to an iterable?

An example from the book Programming the Python kernel on a topic Delegationdoes not seem to work .. Or maybe I did. I do not understand this topic.

Below is the code in which the class CapOpenwraps the object fileand defines the changed behavior filewhen opening in mode write. It should write all lines only in UPPERCASE.

However, when I try to open the file for reading and iterate over it to print each line, I get the following exception:

Traceback (most recent call last):
  File "D:/_Python Practice/Core Python Programming/chapter_13_Classes/
        WrappingFileObject.py", line 29, in <module>
    for each_line in f:
TypeError: 'CapOpen' object is not iterable

This is strange because, although I did not explicitly specify the iterator methods, I expected calls to be delegated through __getattr__to the base object file. Here is the code. Did I miss something?

class CapOpen(object):
    def __init__(self, filename, mode='r', buf=-1):
        self.file = open(filename, mode, buf)

    def __str__(self):
        return str(self.file)

    def __repr__(self):
        return `self.file`

    def write(self, line):
        self.file.write(line.upper())

    def __getattr__(self, attr):
        return getattr(self.file, attr)


f = CapOpen('wrappingfile.txt', 'w')
f.write('delegation example\n')
f.write('faye is good\n')
f.write('at delegating\n')
f.close()

f = CapOpen('wrappingfile.txt', 'r')

for each_line in f:   # I am getting Exception Here..
    print each_line,

I am using Python 2.7.

+5
2

Python :

, , , __getattribute__() ...

__getattribute__() ( , ).

__getattr__/__getattribute__:

, . . .

, __getattr__, , undefined. , , , , . f.__iter__ , , . , .

, , , , , . object, . , Python 3. , , __iter__ self.file.__iter__.

, file __iter__ , .

+12

iterable __iter__ __getitem__.

__getattr__ , - , , Python , , .

:

class Fake(object):
    def __getattr__(self, name):
        print "Nope, no %s here!" % name
        raise AttributeError

f = Fake()
for not_here in f:
    print not_here

, : TypeError: 'Fake' object is not iterable.

:

print '__getattr__' in Fake.__dict__
print '__iter__' in Fake.__dict__
print '__getitem__' in Fake.__dict__

, Python: __iter__, __getitem__, Python , . Python , , , , catching exceptions .

. .

+2

All Articles