Path: csiph.com!usenet.pasdenom.info!nntpfeed.proxad.net!proxad.net!feeder1-2.proxad.net!usenet-fr.net!nerim.net!novso.com!newsfeed.xs4all.nl!newsfeed3.news.xs4all.nl!xs4all!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; 'python.': 0.02; 'syntax': 0.04; 'init': 0.07; 'variables': 0.07; 'assuming': 0.09; 'function:': 0.09; 'instance.': 0.09; 'messing': 0.09; 'rewrite': 0.09; 'subject:hide': 0.09; 'underscore': 0.09; 'cc:addr:python- list': 0.11; 'python': 0.11; 'def': 0.12; 'changes': 0.15; "'n'": 0.16; "(i'm": 0.16; '(note': 0.16; 'check.': 0.16; 'exception;': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'int):': 0.16; 'integer.': 0.16; 'length,': 0.16; 'namespace,': 0.16; 'ought': 0.16; 'subclass': 0.16; 'subject:Not': 0.16; 'subject:possible': 0.16; 'them...': 0.16; 'valueerror': 0.16; 'valueerror,': 0.16; 'exception': 0.16; 'wrote:': 0.18; 'later': 0.20; 'meant': 0.20; 'otherwise,': 0.22; 'cc:addr:python.org': 0.22; 'this?': 0.23; "aren't": 0.24; 'instance,': 0.24; 'skip': 0.24; 'cc:2**0': 0.24; 'this:': 0.26; 'header:In-Reply-To:1': 0.27; 'raise': 0.29; "doesn't": 0.30; 'compared': 0.30; 'message- id:@mail.gmail.com': 0.30; "i'm": 0.30; 'gives': 0.31; 'crash': 0.31; 'ctypes': 0.31; 'int,': 0.31; "they'll": 0.31; 'class': 0.32; 'probably': 0.32; 'option': 0.32; 'up.': 0.33; 'checking': 0.33; 'skip:_ 10': 0.34; "i'd": 0.34; 'could': 0.34; 'problem': 0.35; "can't": 0.35; 'problem.': 0.35; 'something': 0.35; 'equal': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'really': 0.36; 'possible': 0.36; 'should': 0.36; 'changing': 0.37; 'handle': 0.38; 'pm,': 0.38; 'anything': 0.39; 'moving': 0.39; 'changed': 0.39; 'how': 0.40; 'even': 0.60; 'easy': 0.60; 'signal': 0.60; 'break': 0.61; 'length': 0.61; 'new': 0.61; 'simply': 0.61; 'simple': 0.61; 'first': 0.61; 'name': 0.63; 'skip:n 10': 0.64; 'different': 0.65; 'fact,': 0.69; '2015': 0.84; "life's": 0.84; 'works)': 0.84; 'to:none': 0.92; 'average': 0.93; 'instant': 0.97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=SoUwbDUAuCKvG1rR9bxiL8v9AzI1zTyw8Z/ccyej5SI=; b=SxuWeTRT+WxF84N2v8YHxaMLCgs6PJGOq8nZgrHb4MQ8/B149pd30+f7p2ZYzRkS2x WTvIYHyy8ErQHJ9MZWJ7j8wOMJ7eQQwD9ye/xu+uZ5e3+XrcwlRXBLc6Yf4ZfmicCGu9 85cvK3MUjgapnqYlql10WWfzXrU1ha16u08dKcZysffmdtPdsnNzSMsgbzMlfIhG01YP z20DD8y9DZwFlo0D7JQbTx/cHFcIadC2oS46iafdAnYl+UHu0PETW4GwspBp002lHjWQ g3m5vAi3mZh4QaOdBjSWFem1G9Qt9tpuslFsqixQjTC5O5o7GN7rMy3qU7taI/sAPMAE 2E9g== MIME-Version: 1.0 X-Received: by 10.42.227.198 with SMTP id jb6mr16801317icb.12.1430208381246; Tue, 28 Apr 2015 01:06:21 -0700 (PDT) In-Reply-To: <874mo0zoz2.fsf@Equus.decebal.nl> References: <874mo0zoz2.fsf@Equus.decebal.nl> Date: Tue, 28 Apr 2015 18:06:21 +1000 Subject: Re: Not possible to hide local variables From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ 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: 61 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1430208384 news.xs4all.nl 2957 [2001:888:2000:d::a6]:38156 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:89490 On Tue, Apr 28, 2015 at 5:33 PM, Cecil Westerhof wrote: > If I remember correctly you can not hide variables of a class or make > them read-only? > > I want to rewrite my moving average to python. The init is: > def __init__(self, length): > if type(length) != int: > raise ParameterError, 'Parameter has to be an int' > if n < 0: > raise ValueError, 'Parameter should be greater or equal 2' > self.length = length > self.old_values = [] > self.current_total = 0 > > But when someone changes length, old_values, or current_total that > would wreck havoc with my class instance. What is the best way to > handle this? If you simply want them to never change them, but they may look at them, the best option is to do nothing. It's no different from anything else they might do; for instance, someone might inject a new 'type' into your namespace, and completely break your check. (More on that later.) If they aren't meant to look at _or_ change them, what you could do is name them "_length" and so on - a single leading underscore is a signal that this is a private implementation detail, not to be changed or viewed. But you can't stop people from messing you up. You can't stop people from playing around with ctypes and changing the value of 0 (and yes, that is possible - it'll probably crash Python sooner or later though!). None of that is your problem. In fact, it's not really your problem if someone gives you a length that isn't a simple integer. In the first place, they might give you a subclass of int, so a better check would be this: if not isinstance(length, int): raise ValueError("length should be integral") (note that I'm avoiding the multiple-argument syntax which doesn't work in Python 3; if ParameterError is a subclass of ValueError you could use that instead, but ValueError works) You don't even need to check that it's an integer. If you get something that can't be compared against 0, they'll get an instant exception; otherwise, the exception might come up later. But it's still not your problem. You could skip the nonnegativity check too, but that's good documentation. (I'm assuming that ought to be checking 'length', as there is no 'n' in your example.) So here's how I'd write that function: def __init__(self, length): if length < 0: raise ValueError("Length should be non-negative") self.length = length self.old_values = [] self.current_total = 0 If someone changes them... not your problem. Life's so easy when you don't have to worry! ChrisA