Path: csiph.com!usenet.pasdenom.info!aioe.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'finally:': 0.07; 'processing.': 0.07; "'')": 0.09; 'clause': 0.09; 'exception,': 0.09; 'generators': 0.09; 'omit': 0.09; 'strings.': 0.09; 'try:': 0.09; 'def': 0.12; 'itself.': 0.14; '"over': 0.16; '(0,': 0.16; '(1,': 0.16; '(2,': 0.16; '(3,': 0.16; '23,': 0.16; '24,': 0.16; 'empty,': 0.16; 'encoding.': 0.16; 'entirely.': 0.16; 'folks,': 0.16; 'from:addr:mrabarnett.plus.com': 0.16; 'from:addr:python': 0.16; 'from:name:mrab': 0.16; 'iterable': 0.16; 'jumped': 0.16; 'message-id:@mrabarnett.plus.com': 0.16; 'policy:': 0.16; 'received:192.168.1.4': 0.16; 'share,': 0.16; 'shorten': 0.16; 'simplifies': 0.16; 'subject:File': 0.16; 'true:': 0.16; 'tuple': 0.16; 'tuples,': 0.16; 'demonstrate': 0.16; 'wrote:': 0.18; '>>>': 0.22; 'memory': 0.22; 'import': 0.22; 'print': 0.22; 'header:User-Agent:1': 0.23; 'error': 0.23; 'adds': 0.24; 'config': 0.24; 'exists': 0.24; 'specify': 0.24; 'source': 0.25; 'second': 0.26; 'post': 0.26; 'subject:/': 0.26; 'header:In- Reply-To:1': 0.27; 'record': 0.27; 'idea': 0.28; "doesn't": 0.30; 'code': 0.31; 'posting': 0.31; '25,': 0.31; 'with,': 0.31; 'yields': 0.31; 'file': 0.32; 'text': 0.33; 'open': 0.33; 'reader': 0.33; 'subject:with': 0.35; "can't": 0.35; 'except': 0.35; 'but': 0.35; 'disk': 0.36; 'yield': 0.36; 'should': 0.36; 'two': 0.37; 'list': 0.37; 'to:addr:python-list': 0.38; 'files': 0.38; 'rather': 0.38; '(from': 0.39; 'itself': 0.39; 'to:addr:python.org': 0.39; 'either': 0.39; 'how': 0.40; 'flat': 0.60; 'skip:y 20': 0.60; 'tell': 0.60; 'break': 0.61; 'length': 0.61; 'subject: ': 0.61; 'simple': 0.61; 'close': 0.67; '26,': 0.68; 'fox': 0.68; 'subject: & ': 0.68; 'expose': 0.84; 'lazy': 0.91 X-CM-Score: 0.00 X-CNFS-Analysis: v=2.1 cv=eZmzft0H c=1 sm=1 tr=0 a=0nF1XD0wxitMEM03M9B4ZQ==:117 a=0nF1XD0wxitMEM03M9B4ZQ==:17 a=0Bzu9jTXAAAA:8 a=sASEtNAQL0YA:10 a=_C9_Nt7_1MYA:10 a=ihvODaAuJD4A:10 a=IkcTkHD0fZMA:10 a=EBOSESyhAAAA:8 a=2PQYCU_IvbdpxvU7trwA:9 a=0pIgQDNV4CAQykP6:21 a=cn9907NA3zY8pxB9:21 a=QEXdDO2ut3YA:10 X-AUTH: mrabarnett:2500 Date: Sat, 15 Mar 2014 21:56:27 +0000 From: MRAB User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: python-list@python.org Subject: Re: Sharing: File Reader Generator with & w/o Policy References: In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 87 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1394920773 news.xs4all.nl 2949 [2001:888:2000:d::a6]:41310 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:68371 On 2014-03-15 21:38, Mark H Harris wrote: > hi folks, I am posting to share a File Reader Generator which I have > been playing with, that simplifies reading of text files on-demand: > like log files, config files, small record flat data-bases, &c. > > I have two generators to share, one with & one without "policy". > The idea is to have the generator open and close the file (with error > checking: try-finish block) and then maintain its state for on-demand > reading either into memory (as list or dict) or for in-line processing. > > I will demonstrate the generators here, and then post the code > following. The generator will be reading a path+filename of a local disk > file and printing it as in this simple case without policy: > >>> from my_utils import * > > >>> for record in fName(path+"my_fox"): > print(record) > > The quick brown fox jumped > over the lazy dog's tail. > > Now is the time for all > good women to come to the > aid of computer science! > >>> > > The second generator adds "policy" to the generator processing and > yields tuples, rather than strings. Each tuple contains the record > number (from zero), and record length (minus the line end), and the > record itself (stripped of the line end): > >>> > >>> for record in fnName(path+"my_fox"): > print(record) > > (0, 26, 'The quick brown fox jumped') > (1, 25, "over the lazy dog's tail.") > (2, 0, '') > (3, 23, 'Now is the time for all') > (4, 25, 'good women to come to the') > (5, 24, 'aid of computer science!') > >>> > >>> > > I will now share the source by allowing the fName(filename) utility > to expose itself. Enjoy: > >>> > >>> for record in fName(path+"my_utils.py"): > print(record) > > #--------------------------------------------------------- > # fName(filename) generator: file reader iterable > #--------------------------------------------------------- > def fName(filename): > try: > fh = open(filename, 'r') > except FileNotFoundError as err_code: > print (err_code) > else: > while True: > linein = fh.readline() > if (linein!=''): > yield(linein.strip('\n')) > else: > break > fh.close() > finally: > None > I don't like how it always swallows the exception, so you can't tell whether the file doesn't exist or exists but is empty, and no way to specify the file's encoding. Why do you have the 'finally' clause with 'None' in it? Instead of None you should have 'pass', or, better yet, omit the clause entirely. You can also shorten it somewhat: def fName(filename): try: with open(filename, 'r') as fh: for linein in fh: yield linein.strip('\n') except FileNotFoundError as err_code: print(err_code) [snip]