Re: convention for documenting function parameters in doc strings
On Feb 8, 2:49 am, Jean-Michel Pichavant jeanmic...@sequans.com wrote: danielx wrote: Is there aconventionfor how to document function (or method) parameters in doc strings? Recently, I've been doing alot of PHP programming, and in PHPdoc, you'd do it like this: /* * @param type $foo Description. * * @return type Description. */ function bar($foo) { ... } Is there an equivalentconventionI (c|sh)ould be using in my Python docstrings? I saw that Python 3 has function annotations, which could be used for this purpose, but function annotations have no particular purpose within the language itself (which seems like a mistake to me), and they don't exist in the Python 2.x series (at least not the older versions). Different strategies here: 1/ most doc builders propose their own format. You can stick to it if you don't want to use another builder (e.g. epydoc has a specific syntax to document signatures) 2/ Use a 'standard' format, usually these formats are a bit more formal but they gain in portability, most builders support these formats. reStructuredText is one of them and supported by all python doc builders. http://epydoc.sourceforge.net/manual-othermarkup.html JM Thanks for the link, Jean-Michel. I was hoping to find out more about how this is don in reStructuredText, since that seems to be what's used to document Python at docs.python.org. There is a section in the page that you linked to which describes how documenting function parameters in reST works, which seems to be what I was looking for. -- http://mail.python.org/mailman/listinfo/python-list
convention for documenting function parameters in doc strings
Is there a convention for how to document function (or method) parameters in doc strings? Recently, I've been doing alot of PHP programming, and in PHPdoc, you'd do it like this: /* * @param type $foo Description. * * @return type Description. */ function bar($foo) { ... } Is there an equivalent convention I (c|sh)ould be using in my Python docstrings? I saw that Python 3 has function annotations, which could be used for this purpose, but function annotations have no particular purpose within the language itself (which seems like a mistake to me), and they don't exist in the Python 2.x series (at least not the older versions). -- http://mail.python.org/mailman/listinfo/python-list
Re: Pythonic way for handling file errors
On Oct 10, 12:28 pm, Paul Hankin [EMAIL PROTECTED] wrote: On Oct 10, 7:41 pm, wink [EMAIL PROTECTED] wrote: I would like to know what would be considered the most Pythonic way of handling errors when dealing with files, solutions that seem reasonable using 2.5: The best way to handle errors is to catch the exceptions that are raised by the code that handles the error. Your examples push the problem elsewhere: you're setting an error code which has to be tested for. But perhaps your application needs to do this for some reason (judging from your error codes, this is some sort of web script). ... try: with open('afile', 'r') as f: content = f.read() error = 200 except Exception: error = 404 Of all your examples, this is the best. But the catch-all exception handler is bad: it's better to catch just file io exceptions. Also, I think it's better to put the OK case (error 200) in an else clause to make it clearer that it's only set when no error occurs. It's also better to use constants in place of magic numbers. import httplib try: with open('afile', 'r') as f: content = f.read() except IOError: error = httplib.NOT_FOUND else: error = httplib.OK -- Paul Hankin Wink, One of the problems your facing is knowing whether you managed to open the file before reaching the finally block where you close your file. To avoid this, I open my files right before try/finally. For me, the only purpose in having the try/finally is to make sure my files are properly closed, although when I'm lazy, I just let the file close it self during garbage collection. This is what it looks like: file = open('filename') try: # read and/or process file finally: file.close() Of course, this example does not handle any exceptions. In many cases, you want these errors to propogate upward so the users of your functions/methods can decide what needs to be done. On the other hand, you could wrap this code with try/except/else if you wanted to handle the exception at the source. -- http://mail.python.org/mailman/listinfo/python-list
Re: Defining constant strings
I would really like to highlight something Tal has already said: Python strings are immutable. That means if you construct a string object, you don't have to worry about someone else going in and changing that object. What might happen, however, is that someone might reassign a variable you have which points to that object. You can tell people not to do this (although you can't force them) using a mechanism Tal has also described. You give your variable a name which is all caps. Hans wrote: Hi, I want to define a couple of constant strings, like in C: #define mystring This is my string or using a const char construction. Is this really not possible in Python? Hans --=_NextPart_000_004E_01C6C9FF.C5137CF0 Content-Type: text/html; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Google-AttachSize: 902 !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.0 Transitional//EN HTMLHEAD META http-equiv=Content-Type content=text/html; charset=iso-8859-1 META content=MSHTML 6.00.2900.2604 name=GENERATOR STYLE/STYLE /HEAD BODY bgColor=#e6e3df DIVFONT face=Arial size=2Hi,/FONT/DIV DIVFONT face=Arial size=2/FONTnbsp;/DIV DIVFONT face=Arial size=2I want to define a couple of constant strings, like in C:/FONT/DIV DIVFONT face=Arial size=2#define mystring This is my string/FONT/DIV DIVFONT face=Arial size=2or using a const char construction./FONT/DIV DIVFONT face=Arial size=2/FONTnbsp;/DIV DIVFONT face=Arial size=2Is this really not possible in Python?/FONT/DIV DIVFONT face=Arial size=2/FONTnbsp;/DIV DIVFONT face=Arial size=2Hans/FONT/DIV/BODY/HTML --=_NextPart_000_004E_01C6C9FF.C5137CF0-- -- http://mail.python.org/mailman/listinfo/python-list
Re: Optimizing Inner Loop Copy
Mark E. Fenner wrote: Paul McGuire wrote: Mark E. Fenner [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Hello all, snip Here's my class of the objects being copied: class Rule(list): def __init__(self, lhs=None, rhs=None, nClasses=0, nCases=0): self.nClasses = nClasses self.nCases = nCases Ok, so here are some bigger picture kind of questions. 1. Do you need to construct all these Rule objects in the first place? Sorry, I had a nice response written out ... and I lost it. Here's the summary. Unfortunately, yes, the algorithm this code implements goes to great lengths to ensure that each possible Rule is generated only once. 2. More of an OO question than a performance question, but why does Rule inherit from list in the first place? Is Rule *really* a list, or is it just implemented using a list? It is the later. And it is a moderate abuse to say that the Rule _isa_ list. Aside from the two integer statistics (nClasses, nCounts), the RHS and LHS can be merged and we can say that the rule is [(tuple1), ..., (tupleN), (tupleRHS)] with the RHS being Rule[-1]. However, in that case, I went for OO principles and kept the two logical parts separate. B/c of the frequency of list operations, it's better to be able to use thisRule.append() or thisRule[i] then thisRule.lhs.append() or thisRule.lhs[i]. Where speed doesn't matter, I have the more appropriate thisRule.addLHS(). Yes, I could do dot removal (i.e., localize the attribute lookups), but when we iterate over a whole set of Rules, this still leave the localization assignment inside an inner loop. Then maybe you can assign an unbound method (eg, append = list.append), then pass in your instance as the first argument (eg append( myList, newElement )). Even if you localize a bound method, it should save some time, no? If the latter, then you might look at moving Rule's list contents into an instance variable, maybe something called self.contents. Then you can be more explicit about appending to self.contents when you want to add lhs to the contents of the Rule. For example, why are you calling extend, instead of just using slice notation to copy lhs? Ah, because then you would have to write something like self = lhs[:], which doesn't look like it will work very well. On the other hand, if you use containment/delegation instead of inheritance, you can use the more explicit self.contents = lhs[:]. In fact now you have much more control over the assemblage of rules from other rules. Fortunately, the Rules are only assembled in one way ... appending to that copy that started the thread. Incidentally, by speeding up Rule.__init__ and inlining it (instead of calling Rule.copy which called Rule.__init__), that is no longer my bottleneck *phew*. In the original post, you state: the left hand side of a rule (e.g., a rule is a b c - d) is self and three other pieces of information are kept around, two ints and a right hand side What other aspects of list are you using in Rule? Are you iterating over its contents somewhere? Then implement __iter__ and return iter(self.contents). Are you using if rule1: and implicitly testing if its length is nonzero? Then implement __nonzero__ and return operator.truth(self.contents). Do you want to build up rules incrementally using += operator? Then implement __iadd__ and do self.contents.extend(other.contents), or self.contents += other.contents[:] (no need to test for None-ness of other.contents, we ensure in our constructor that self.contents is always a list, even if its an empty one). Well, I do several of these things ... many of them inside inner loops (there's a sequence of inner loops ... the algorithms choice, not mine). Each of these that are implemented (and not left to Python's builtin list methods), is an extra level of function call overhead. This has been a secondary project for me over a number of years ... so I have to look at my early revisions, but I think my original architecture was an explicit self.lhs = [] attribute. And it was REALLY slow. When Python allowed inheritence from builtin objects, I tried it and got a nice win (I think!). Save inheritance for the true is-a relationships among your problem domain classes. For instance, define a base Rule class, and then you can extend it with things like DeterministicRule, ProbabilisticRule, ArbitraryRule, etc. But don't confuse is-implemented-using-a with is-a. Well, I know the difference and choose to break the rule intentionally *chuckle*. After the initial prototype, speed trumped OO. -- Paul Thanks for your comments, Paul. Regards, Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: hide python code !
Steven D'Aprano wrote: On Wed, 16 Aug 2006 13:39:10 -0700, danielx wrote: Steven D'Aprano wrote: On Tue, 15 Aug 2006 09:00:16 -0700, Ben Sizer wrote: Yes, in much the same way that there is no point ever locking your doors or installing burglar alarms, as a determined thief will eventually steal your belongings. That's an utterly pointless and foolish analogy. (1) If a thief breaks into your house and steals your TV, you no longer have a TV. If a developer sees your code, you still have your code, *even if they subsequently copy it*. You haven't lost your code, it is just no longer secret. Since secrecy is rarely valuable in and of itself, you've lost nothing. But haven't you lost your control over the code? If you were trying to sell a program (regardless of whether this is a good way to make money from it), hasn't your ability to do so been undercut? This is the loss. Maybe so. And if a competitor creates a better product than yours, hasn't your ability to sell your program been undercut too? Creating a better product is a legitimate activity (that's what the market system is trying to promot after all (not saying the market system is right, but it is relevant since many people believe in it)). The whole question is whether copying your code is legitimate. Drawing an analogy from art and clearly patent-able products, it seems software might fall into the same category of protectable products. Again, this is the question at hand. Either scenario has NOTHING to do with thieves breaking into your house and locks on doors. The analogy is bogus. Undercutting your ability to sell a product is not theft, and compiling source code to machine code is not analogous to a lock on the door. Yes, I've heard all the stories about valuable algorithms and the like. Some of them might even be true. But for 99+% of code, spending even one cent to keep it secret is just wasting money. That may be true, but for someone who has determined that the hiding the code would be best, it would seem to be quite a good investment. Whether it seems to be a good investment is quite different from whether it *is* a good investment. If they ask me for advice, I'll tell them that they're almost certainly wasting their time, that their algorithm almost certainly isn't as valuable as they think, and that if they disagree, well, Python supports So it's your opinion against the author's, no? And the decision is up to the author, and not you, no? .pyc files, there are tools like py2exe which will put their Python code inside an exe file, there is a Python obfuscator, and a few other tricks. If none of those things are good enough for them, then Python is not the language they want to be using. That seems good, but you also seem to have something against the whole idea of stronger protections for Python. I don't think loose protections has to be an inherent feature of Python. As for the rest of your post, it is mostly irrelevant. However, I will answer one last point: [snip] Even if we don't take the twice figure literally, I imagine that most of us would agree that the amount that the bar can be raise is considerable and not insignificant. I dispute that most of us agree that the bar can be raised a considerable amount. It is my position that in the real world, as opposed to the fantasies of amateur programmers, compiling code is virtually NO BARRIER to your competitors understanding your algorithm. Anyone willing to take a good survey? Until then, I think we can just disagree over that point. Perhaps you would like to consider how it is that black-hat hackers and virus writers can analyse Microsoft Windows for vulnerabilities and security holes *without access to the source code*? Yes, but wouldn't it be much easier for those vulnerabilities to be discovered if the code were released? Black-hats also have to advantage that MS announces vulnerabilities for them, which they take advantage of during the period where people are patching their windows. (And by the way: your suggestion that Microsoft has very few workers is wrong. Microsoft has approximately 60,000 employees, and that almost certainly doesn't include the many sub-contractors they hire. http://www.networkworld.com/news/financial/microsoft.html ) I'd say that's not a large number (I was more or less aware that ms has ten's of thousands of emploees), but obviously you'd disagree with that... -- Steven D'Aprano -- http://mail.python.org/mailman/listinfo/python-list
Re: hide python code !
Paul Boddie wrote: danielx wrote: But we have only considered the economics of such a decision. Even if there is no market value to a work, a person has an understandable desire to exercise the rights of ownership over a work, given the amount of personal investment one makes in producing it. There are other motivations, too. An author might wish that their work convey a particular message and that others should not be able to make derived works which distort or contradict that message. However, there are various established principles of fair use which limit the author's control over such derived works. [...] I think the above idea is frequently missed in discussions about copyrights/patents in the open source world. There, the focus seems to be on the marketability granted by protections (legal or physical). The post I am responding to illustrates this focus. Do we believe an author forfeits ownership of a work merely by sharing it? As a matter of conscience, I don't believe the answer can be imposed on anyone. Every person must answer this for him or herself. As we've mentioned above, one crucial issue is control over published works and over the potentially related works of others. With software, such control is mediated by the licence which is often prominent, even unavoidable when using proprietary software; thus, people using or distributing software should be aware of the licence which applies to the work. In contrast, works in areas such as popular music are not While I agree with most of your post, I think the point should be made that eula's don't hold up very well in US courts: http://en.wikipedia.org/wiki/EULA#Enforceability prominently labelled with licensing information if you're listening to that music playing on the radio, television, in a public space, and so on. This apparent promiscuity with such works leads people to believe that they are freely exchangeable and that the author is not exercising control, even if that isn't really the case due to the framework established by the recording industry for broadcasters. So, people perceive an apparent lack of control as some kind of lack of ownership, that the work has, by being shared in an apparently Extremely interesting point! This should really motivate people to answer the question I posed earlier: Does an author of software forfeit his rights to the code if he shares his program (ie, reliquishes _complete_ protection over the code)? Let's say this happens: I want to sell some software, but I'm affraid people will just copy it. So I prototype it in Python (or whatever programming language) and never release the program. Based on that, I design a chip (I know this is nearly impossible, but we are doing a mental experiment), which does exactly the same thing. First of all, the chip can be reverse engineered (of course, with MUCH greater difficulty than the equivalent code). Should I still be worried that my invention will be copied? A second point to consider: The chip is patentable (I think this is the case legally, as well as in the court of public opinion), so what about the equivalent code? unconditional way, become part of their common culture - a sentiment or an understanding that can presumably be traced back throughout the history of human culture itself. At the opposite end of the spectrum of control, when mechanisms of control are used to restrict the distribution of derived works or the production of coincidentally related works, is it unfair that people wish to disregard such apparently counter-intuitive mechanisms? An interesting example in popular culture was the legal argument about whether silence constitutes an original work (http://news.bbc.co.uk/1/hi/entertainment/music/2133426.stm), but things like patents affect the ability of others to create works in a fashion that can be much harder to predict. Paul -- http://mail.python.org/mailman/listinfo/python-list
Re: Optimizing Inner Loop Copy
Mark E. Fenner wrote: Mark E. Fenner wrote: John Machin wrote: Mark E. Fenner wrote: Here's my class of the objects being copied: Here's a couple of things that might help speed up your __init__ method, and hence your copy method: class Rule(list): def __init__(self, lhs=None, rhs=None, nClasses=0, nCases=0): def __init__(self, lhs=None, rhs=(), nClasses=0, nCases=0): self.nClasses = nClasses self.nCases = nCases if lhs is not None: self.extend(lhs) what does the extend method do? If it is small, perhaps inline a copy of its code here. if rhs is None: self.rhs=tuple() else: self.rhs=rhs Replace the above 4 lines by: self.rhs = rhs HTH, John John, Thanks. I thought of those at the same you did! I also incorporated one other use of the default=() + no conditional: class Rule(list): def __init__(self, lhs=(), rhs=(), nClasses=0, nCases=0): self.nClasses = nClasses self.nCases = nCases self.extend(lhs) # note, self is a list so this is list.extend self.rhs=rhs def copy(self): return Rule(self, self.rhs, self.nClasses, self.nCases) Actually, I also removed the passthrough that copy was doing and just called the constructor directly. So, at the top level code, we have: allNew = [] for params in cases: # newobj = initialObject.copy() newObj = Rule(initialObject, initialObject.rhs, initialObject.nClasses, initialObject.nCases) newObj.modify(params) allNew.append(newObj) return allNew Regards, Mark I'm not sure how much this will help, but another thing you can do is put this line before the for: append = allNew.append Then, replace the last line in the loop with append(newObj) Check out this doc for more info on optimizing Python, and the section which talks about eliminating dots: http://wiki.python.org/moin/PythonSpeed/PerformanceTips http://wiki.python.org/moin/PythonSpeed/PerformanceTips#head-aa6c07c46a630a2fa10bd6502510e532806f1f62 -- http://mail.python.org/mailman/listinfo/python-list
Re: hide python code !
Steven D'Aprano wrote: On Tue, 15 Aug 2006 09:00:16 -0700, Ben Sizer wrote: Yes, in much the same way that there is no point ever locking your doors or installing burglar alarms, as a determined thief will eventually steal your belongings. That's an utterly pointless and foolish analogy. (1) If a thief breaks into your house and steals your TV, you no longer have a TV. If a developer sees your code, you still have your code, *even if they subsequently copy it*. You haven't lost your code, it is just no longer secret. Since secrecy is rarely valuable in and of itself, you've lost nothing. But haven't you lost your control over the code? If you were trying to sell a program (regardless of whether this is a good way to make money from it), hasn't your ability to do so been undercut? This is the loss. Yes, I've heard all the stories about valuable algorithms and the like. Some of them might even be true. But for 99+% of code, spending even one cent to keep it secret is just wasting money. That may be true, but for someone who has determined that the hiding the code would be best, it would seem to be quite a good investment. Besides, these kinds of decisions are made case by case. We would not throw a dice to see whether some code should be released or not. Of course, these kinds of statistics _should_ moderate any decision, but I don't think you can expect that 99+% will make sense to most (intelligent) people. But we have only considered the economics of such a decision. Even if there is no market value to a work, a person has an understandable desire to exercise the rights of ownership over a work, given the amount of personal investment one makes in producing it. It's reall just a form of acknowledgement (you may consider an alternative form of acknowledgement more rewarding, but we are talking about the author, not you). Considering the investment justificiation, I find it difficult to deny an author the right to his or her own work (the right to a work, of course, implies the option to protect it). I think the above idea is frequently missed in discussions about copyrights/patents in the open source world. There, the focus seems to be on the marketability granted by protections (legal or physical). The post I am responding to illustrates this focus. Do we believe an author forfeits ownership of a work merely by sharing it? As a matter of conscience, I don't believe the answer can be imposed on anyone. Every person must answer this for him or herself. (2) Compiling code to machine language isn't like locking your door. Compiling code doesn't prevent me from seeing your code or your algorithm, If a house is locked, it can still be entered (without the key). The point is not that it is impossible to break in, but that it is more difficult. it just means I see it written in machine language instead of C. If I know how to read machine code, or if I have a decompiler, then I can read it, no problems at all. Would you argue that Python source code hides your I know how to read asm, but if you say anyone can read asm just as easily as one can read Python or even C, then you must be referring to a machine. algorithm because it is inscrutable to people who can't read and understand Python? Surely not. So why do you argue that compiled code is hidden merely because it is inscrutable to people who don't know how to download a decompiler off the Internet? It's all a matter of degree. The question of plausibility is always relevant. (3) Compiling code is certainly not like installing a burglar alarm. When I decompile your code, no alarms ring and you are not notified. That's pretty nit-picky... I find it strange that people (at least on c.l.py) often equate 'imperfect protection' with 'pointless protection'. Nonsense. Can I remind you that the Original Poster *explicitly* rejected using Python's imperfect code-hiding technique (distribute only the compiled .pyc files) because they can be disassembled, but failed to realise that EXACTLY the same argument holds for compiled C code? Let me make it clear with a better analogy than your locked door one: the O.P. says I don't want people to look through the windows of my Python house. I thought about hanging curtains, but people with thermal imaging equipment can see right through the walls. Can I hang vertical blinds in Python like my C programmer friends? The answers are: (1) No, Python uses curtains. If you want vertical blinds, use another language. (2) Even if you hang vertical blinds, it isn't going to stop people with thermal imaging equipment from seeing into your house and copying your algorithm, just like they can with Python. The all-or-nothing attitude makes no sense. If you can halve the number of people who can deduce your algorithm, that helps. If you can double the time it takes for those people to deduce it, that also helps. If it took you months of RD, the value of even
Re: include a python class in another python script.
KraftDiner wrote: I have a class that is defined in a file called MyClass.py How do I use that class in another python script.. import MyClass ? (Does it need to be in a specific location?) MyClass.py has to be on your python path. Your python path is a list of directories python will search (in order) when you do an import statement. By default, your current working directory is the first place Python will search. You can also customize your python path. Check out this part of the docs for more info: http://docs.python.org/inst/search-path.html#search-path -- http://mail.python.org/mailman/listinfo/python-list
Re: hide python code !
Fuzzyman wrote: Bayazee wrote: hi can we hide a python code ? if i want to write a commercial software can i hide my source code from users access ? we can conver it to pyc but this file can decompiled ... so ...!! do you have any idea about this ...? --- First Iranian Open Source Community : www.python.ir You can distribute the compiled byte-code files (*.pyc) which are harder to turn back into source code. There was a product called decompyle which could do it, but although there is a version floating around which works for Python 2.4 I've never heard of anyone getting it to work. Import hooks and encrypted source are a good option. Py2exe embeds the byte-code file for your main script into the executable which is also pretty good. All of these make it hard enough to deter most people who will ever want to abuse your source code. Until you have *lots* of users this is probably enough. I never understand the knee-jerk reaction on this mailing list to answer people who ask this question by telling them they don't really want to do it... I'm I've compained about this before, but I'd say people apply that response to alot of other things too here on this mailing list. *** Earlier in this thread, people were making alot of noise about Bayazee trying to protect the code while it seemed he was part of an open source group. He never mentioned that he intended to hide any code produced for this open source group; indeed, he never mentioned any code he wished to hide at all. People must have been inferring that if one is part of an open source group, that all work one produces is for the group and must therefore be open source. Otherwise, people might have been thinking that being a member of an open source group makes you an open source evangelist. If the latter is true (and these cases are neither mutually exclusive nor exhaustive), then those who were so vocal in pointing out the appearant discrepency must have been projecting their own views on Bayazee. I'm not sure if this needs to be said, but just because someone posts on comp.lang.python does not mean he or she believe (or even should believe) the same things as you! My last statement applies to a few other things I've read around here, but I'm going to be done for now... Fuzzyman http://www.voidspace.org.uk/python/index.shtml -- http://mail.python.org/mailman/listinfo/python-list
Re: selecting base class from user input
Jackson wrote: Thanks for the reply. danielx wrote the following on 2006-08-13 19:49: Is your declaration of ABC supposed to have some_super as one of the base classes? Your constructor has some_super as a parameter. What is this supposed to mean in light of the declaration for ABC? Indeed, my goal is to have the base class of ABC determined dynamically via a parameter passed into the constructor. If you are trying to customize the base class of ABC by passing an argument to the constructor of ABC, you should probably reconsider. If constructing one instance of ABC can change ABC (the class) itself, then the behavior of other instances will be affected as well. No programmer can stay sane if he creates instances of a class that could suddenly change its behavior (due to someone else's code). Fortunately, the ABC class is not very useful. In fact, it was mostly just to be used to store particular examples of the user-specified base class. So all method calls would be from the base class only. What you could do instead is to create a function which constructs classes based on the arguments it recieves. Then, you'll be able to create instances of the generated classes (all this meta-thinking is huring my brain ;). I am talking about something like this: def createClass(name, base): exec class %s(%s): pass % (name, base) return eval( name ) In fact, this is exactly what I ended up doing. def example(base): if base == SomeClass: # call SomeClass.__init__(self) # build example as it would look in SomeClass elif base == SomeOtherClass: # call SomeOtherClass.__init__(self) # build example as it would in SomeOtherClass Can you please tell us why you are doing this? My curiosity is killing me! So here is a good example: I have 4 classes: Lion(Animal): Ant(Animal): Bee(Animal): Human(Animal): which are all subclasses of some superclass called Animal. Now I want to define an occupation. For example, Worker. A worker can exist as any of the 4 classes above. Their constructors are different and I might want to add certain features. My first thought was to create a class called Worker and have the base class determined by a variable which is passed into the constructor. What you should keep in mind though, is the is-a relationship that subclasses are supposed to have with their parents. worker is a lion does not make sense. What you want instead is LionWorker. You'll end up doing only a little more typing than if you had a general Worker class, but I don't think it will be much more. If your *Worker classes have really simple bodies, you might be able to automate the creation of your *Worker classes by doing something like the createClass function (ie, by creating the classes dynamically instead of using the class statement). I also discovered another way to dynamically create classes, described in this article (the article talks about other things as well): http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html I'm not sure if this will help you, but it's definitely interesting. Most of the method calls will come from the Animal superclass anyway, but some method calls might come from the Lion class, for example. Now I realize this would drive a programmer crazy...because a Lion might have a roar() method whereas a Human might have a holler() method. But so long as the user knew which argument they passed in, it shouldn't be too difficult to keep track of it. So for example (again, I know what I am typing doesn't actually work)... Worker(some_animal): def __init__(self,some_animal): # change the base class to some_animal if some_animal == Lion: # give the lion a big mane if some_animal == Ant: # make the ant dumb if some_animal == Bee: # make the bee know how to dance if some_animal == Human # give the human a hardhat def work(self, hours): # tell the animal to work for the specified number of hours if some_animal == Lion: self.cat_nap(hours) if some_animal == Ant: self.walk_back_and_forth(hours) if some_animal == Bee: self.buzz_and_dance(hours) if some_animal == Human: self.use_hammer_on_coworker(hours) # notice, a Human does not have a cat_nap method def take_lunch(location): and so on. So the thought is that a Worker can exist in many different forms: as a lion, as an ant, as a bee, and as a human. And I might want a single worker class that represents them all. Hopefully this makes sense. Another meta-thought: Hopefully I've beaten everyone else to the punch about that question. Is it just me, or will a reply with such a question always tell the original poster that what he wants to do MUST be flawed? I hope I have been gentler than
Re: selecting base class from user input
Jackson wrote: Maric Michaud wrote the following on 2006-08-14 01:26: In [28]: class Animal(object) : : _types = {} : : In [29]: class Worker(object) : : def work(self) : print 'hard' : : [snip] What you are trying to achieve is more commonly done by agregation and delegation : In [47]: class Lion(Animal) : : def __init__(self, *classes) : : self._objects = tuple(c() for c in classes) : def isA(self, class_) : : return class_ in (type(o) for o in self._objects) : def __getattr__(self, name) : : for obj in self._objects : : try: return getattr(obj, name) : except: pass : raise AttributeError('not defined or found in objects %s' % name) : : In [48]: Lion().work() --- exceptions.AttributeErrorTraceback (most recent call last) /home/maric/ipython console /home/maric/ipython console in __getattr__(self, name) AttributeError: not defined or found in objects work In [49]: Lion().isA(Worker) Out[49]: False In [50]: Lion(Worker).isA(Worker) Out[50]: True In [51]: Lion(Worker).work() hard This is exactly what I am looking for. However, I am not sure how to implement different Worker methods. For example, a Lion might work differently than an Bee. In my example, the Lion would take a cat-nap while the Bee might do a dance. It seems that I would need to what kind of class called the work() method. Is there a way to do that? If all of your animals are supposed to be workers, maybe you should declare your animal classes like this: class Lion(Animal, Worker): def work(self): pass Your Worker class might not have a work method (or it might have one which does no work, pun intended), even though the methods it does have depend on an instance being able to respond to a work call. Then, the Worker class is like an abstract class in Java (cross yourselves). This is an example of delegation which someone here has already mentioned. In that case, users will most likely never instantiate Worker, but none of the Worker code needs to be replicated, because Lion (or whatever) is a subclass of Worker. This is one of the benefits of OOP :P. Even if I could do that, it seems these various definitions of work should probably go into the class of the animal---so that Lion actions are all within the Lion class. Thus, the Lion class should have its own work method, and the Bee class should have its own work method as well. The problem with this is that every Lion can use the work method, when I really only work Workers to use the work method. I can picture another way of achieving this...have a list of occupations...which are booleans for each instance of the class. Then the work() method will call only if the Worker boolean is True. This should be sufficient...and the differing work methods would be in their respective classes. However, now the actual method names are not uniform---that is, it becomes a bookkeeping exercise to remember that when Worker is True, then the method to create is work(), that when Student is True, then the method to create is study(). So this procedure has its own problems too. It seems like I am trading off hardships now. So here is what I am looking for: A single Worker class with a standardized set of method names. The In Java (cross-ing ritual), you would create an interface, which requires a work method. But this is Python :P. We just don't do that. Search the following page for easier to ask for forgiveness and look before you leap on this page (the glossary of Guido's Python tutorial): http://docs.python.org/tut/node18.html methods in the Worker class are dependent on the superclass (via aggregation and delegation, as shown above) of the worker. That is, a Bee performs different actions when working than a Lion or a Human. And finally, the occupations such that not every Bee is a worker and there are some Workers which are Bees. Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: selecting base class from user input
Is your declaration of ABC supposed to have some_super as one of the base classes? Your constructor has some_super as a parameter. What is this supposed to mean in light of the declaration for ABC? If you are trying to customize the base class of ABC by passing an argument to the constructor of ABC, you should probably reconsider. If constructing one instance of ABC can change ABC (the class) itself, then the behavior of other instances will be affected as well. No programmer can stay sane if he creates instances of a class that could suddenly change its behavior (due to someone else's code). What you could do instead is to create a function which constructs classes based on the arguments it recieves. Then, you'll be able to create instances of the generated classes (all this meta-thinking is huring my brain ;). I am talking about something like this: def createClass(name, base): exec class %s(%s): pass % (name, base) return eval( name ) ... Can you please tell us why you are doing this? My curiosity is killing me! Another meta-thought: Hopefully I've beaten everyone else to the punch about that question. Is it just me, or will a reply with such a question always tell the original poster that what he wants to do MUST be flawed? I hope I have been gentler than this. Jackson wrote: I want a class that will determine its base class by the argument passed in. What I am about to write _does_not_work_, but it shows what I am trying to do. class ABC(some_super): def __init__(self,some_super): some_super.__init__(self) if some_super == list: self.append('ABC') elif some_super == dict: self['ABC'] = None Then, the user can call this function: example = ABC(list) print example ['ABC'] example = ABC(dict) print example {'ABC': None} Clearly, this is a bad example, but the central idea is what I am trying to do. ABC is a particular example which can be represented in various forms. I want an ABC class that will create the example in the form specified by the user. So how can I achieve this? Thanks. -- http://mail.python.org/mailman/listinfo/python-list
Re: semi-Newbie question
len wrote: Hi all I have a file that I receive from another party which is basicly a csv file containing the following type of information; Python has a csv module. I'm not sure if you're already using that or if it would be useful to you: http://docs.python.org/lib/module-csv.html Tagname Scope Value first_name,POL01,John last_name,POL01,Doe birthday,POL01,04/03/61 etc I need to convert this file info into my file format used in my application. I have been given a file from the other company that gives me all of the tagname that could be used and their scope. I want to build a So, a tag name is like a field name, right? What's a scope? table which would have all of the various tagnames, scope, and put a fieldname equivalent in the fieldname in my file structure in my application. Then read through the vendors csv file index into my table file and get the field name of where to move the data into my data structure. Here is my question? basicly I need to get the data referenced by fieldname variable in my table and then use that data as a variable name in a python assignment statement. Thus changing the actual python code at each iteration through the lines in the csv file. I'm not sure that you need to have a different statement execute during each loop. Why not have something like this: for line in tagfile: foreignTag, scope, value = parse(line) currentRow[ myEqvTag(foreignTag) ] = value ## do you want to do something with the scope information? If you really wanted to, you could use exec/eval and construct a string you want to execute/evaluate, but people tend to look down on that. At least one of the reasons is that it would be slower. Just for completeness, maybe this is what you want: for line in tagfile: ft, sc, v = parse(line) exec %s = %s % ( myEqvTag( ft ), v ) Is this something like what you wanted? I'm not quite sure what you're asking... More code might help. Good Luck! for i in tagfile find tagname in tagtable *** the following line of code would change through each iteration *** myfirst = value *** next iteration mylast = value *** next iteration mybirth = value etc I hope this make sense. I remember seeing something like this somewhere. Any help appreciated. Len Sumnler Unique Insurance -- http://mail.python.org/mailman/listinfo/python-list
Re: Open file handles?
Is there an equivalent in windows? Jon wrote: Perhaps using os you could work with lsof [http://www.linuxcommand.org/man_pages/lsof8.html] Jon Thomas Bartkus wrote: This may be more of a Linux question, but I'm doing this from Python. . How can I know if anything (I don't care who or what!) is in the middle of using a particular file? This comes in context of needing to copy a file BUT only if I can verify that something else doesn't have an open write handle to that file. IOW - I need to decline the operation if something else hasn't finished writing to the file. How can I know? Thomas Bartkus -- http://mail.python.org/mailman/listinfo/python-list
Re: Why do I require an elif statement here?
I'm surprised no one has mentioned neat-er, more pythonic ways of doing this. I'm also surprised no one mentioned regular expressions. Regular expressions are really powerful for searching and manipulating text. Here is where I learned most of the stuff I know about regular expressions: http://www.amk.ca/python/howto/regex/ I think this howto does a pretty good job, and doesn't take too long to read. Anyway, here's my solution, which does Not use regular expressions: def reindent(line): ## we use slicing, because we don't know how long line is head = line[:OLD_INDENT] tail = line[OLD_INDENT:] ## if line starts with Exactly so many spaces... if head == whitespace*OLD_INDENT and not tail.startswith(' '): return whitespace*NEW_INDENT + tail else: return line# our default emptyString = lines = input.readlines() reindented = [reindent(ln) for ln in lines] output.write( emptyString.join(reindented) ) I'll bet you could put that all on one line using lambda instead of a def, but this is Python, and we like clarity ;). A regular expression could have taken the place of our reindent function, but I'll leave that up to you to explore ;). Jim wrote: Good stuff! Since I'm only interested in spaces being my only whitespace it makes sense for me to use line.lstrip(whitespace) in my script, thus eliminating the elif char == '\n': statement. Thanks, Jim Tim Chase wrote: Hard to believe that lstrip() produces an empty string on lines with just spaces and doesn't remove the '\n' with lines that have characters. It's easy to understand that lstrip() is doing exactly what it's supposed to. It evaluates from the left of your string, discarding whitespace (spaces, tabs, and cr/lf characters) until it hits a non-whitespace character or the end of the string. When there's no non-whitespace, it returns an empty string. If you wanted to remove the \n from the right of lines, there was an earlier discussion on the list where someone (Bruno?) and I went back and forth and I think we finally decided that the best solution was s.rstrip('\n') which had the fewest side-effects. However, when you use the output.write() method, you'd then have to add the \n back in to make sure it ended up in the output stream. If you wanted to continue to use lstrip(), you could also just ensure that you're only stripping spaces (chr(0x20)) by using s.lstrip(' ') This would leave \t and \n characters unmolested. More info can be found at help(.lstrip) help(.rstrip) help(.strip) Hope this helps, -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: Nested function scope problem
Gerhard Fiedler wrote: On 2006-08-05 09:30:59, Antoon Pardon wrote: But this means that C variables are not analog to Python variables, [...] Yes they are. Nobody so far has been able to create a simple table with analog operations Python vs C that operates on C /variables/ (not dereferenced pointers) and makes any sense. (Similar to the one Dennis just posted.) At least for me, the point is that Python variables are precisely analogous to C pointers (single star-ed); furthermore, there is nothing analogous to C primitives (ie, C int, float, etc.); and the are no references to references, only references to heap data. I have two ways of explaining this. The first uses alot of word chopping, making it rather long winded. The second relies on the notion of a homomorphism used in abstract algebra. You may be able to follow along even if you don't already know what a homomorphism is, but that explanation will most likely benefit people who already do. explanation attempt 1: When I say things like num1 is 'holding' a long, I am being quite loose with the word holding. Literally, I would say the variable is holding a reference. But references are the only thing Python variables can hold; therefore, our loosely worded phrase can unambiguously taken to mean that the reference held by num1 points to a some long struct. This loose way of saying things tends to imply that the reference IS the long itself (even though we have to follow the reference to reach the actual data). From this, we can easily derive a notion of identity in Python: two things are identical if they are the same address (remember, all things are references). This make sense because if we have list1 is list2, then changes to list1 are also seen in list2 comment: Unfortunately, I had to switch examples in the second paragraph, since long is an immutable type. On the plus side, this illustrates the deep consequences of immutable data types in Python. explanation attempt 2 (me being a pretentioius ass): I claim that there is some structure preserving function, a homomorphism, which goes from Python variables to C variables when we are working with the '+' operator in Python and the AllocateAndConsInteger( *dot + *dot ) operator in C. To illustrate what the AllocateAndConsInteger function does, the following are supposed to be analogous: Python: ## initialize aPy and bPy aPy = 1; bPy =2 xPy = aPy+bPy # --OPERATE ~ C: /* declarations: annoying, but necessary */ int * aC, *bC, *xC; /* initialize a and b */ aC = (int *) malloc(sizeof(int)); bC = (int *) malloc(sizeof(int)); *aC = 1; *bC = 2; xC = AllocateAndConsInteger( *a + *b ) /* -- OPERATE */ I think you can imagine a function f where the following (always) holds: f(aPy) == aC and f(bPy) == bC and f(xPy) = xC Then f is a homomorphism... Earlier, I described the above as reasoning. Don't take that too literally ;). ... All of what I have been saying has been an attempt at getting across what I had hoped to acomplish with my remote-in-cup analogy. Unfortunately, it's very hard to do the analogy real justice without good illustrations, which you will find in Head First Java. It's really a fun book... Just do it (I mean state a few operations on/with variables in either language, and what the analog operation in the other language is), and I may be a convert :) [...] C dereferenced pointers are. No they are not. a = b in Python translates to: a = b in C. It doesn't translate to *a = *b in C. Hold this thought for a little while... It is true that a = b + c in Python doesn't translate to a = b + c in C, but since this really is a shortcut of a = b.__add__(c) there is nothing wrong with tranlating it into something like: a = IntPlus(b, c) for C, where the IntPlus will provide a new pointer that points to the sum [...] Did you hold that thought? Now IntPlus() returns a new pointer, which means that c is a pointer variable, not a value variable. Didn't you write above that it wasn't a pointer? or we could provide the necessary structures so that we could translate is as: a = b-__add__(c) Which of course again requires b to be a pointer. You seem not to be clear whether you want to create a C analogy (to Python variables) of C variables (as you stated above) or of C dereferenced pointers (as your code examples show). [...] then there is something in C deserving the term variable which behaves like variables do in Python. ?? There /is/ something in C called a variable. And there is something in Python (at least commonly) called variable. But IMO they don't behave in a similar way. (It is obviously possible to create something in C that behaves like a Python variable, but that's then not a C variable. It's a more complex C construct.) Gerhard -- http://mail.python.org/mailman/listinfo/python-list
Re: Why do I require an elif statement here?
No offense. I didn't mean there was anything wrong with your way, just that it wasn't neat. By that, I meant, you were still using lots of for loops and if blocks. Justin Azoff wrote: danielx wrote: I'm surprised no one has mentioned neat-er, more pythonic ways of doing this. I'm also surprised no one mentioned regular expressions. Regular expressions are really powerful for searching and manipulating text. I suppose I put those things too close together. I meant I was surprised for each of the two Separate (non)occurances. [snip] I'm surprised you don't count my post as a neat and pythonic way of doing this. I'm also surprised that you mention regular expressions after neat and pythonic. While regular expressions often serve a purpose, they are rarely neat. Anyway, here's my solution, which does Not use regular expressions: def reindent(line): ## we use slicing, because we don't know how long line is head = line[:OLD_INDENT] tail = line[OLD_INDENT:] ## if line starts with Exactly so many spaces... if head == whitespace*OLD_INDENT and not tail.startswith(' '): return whitespace*NEW_INDENT + tail else: return line# our default [snip] This function is broken. Not only does it still rely on global variables to work, it does not actually reindent lines correctly. Your It's just an illustration. function only changes lines that start with exactly OLD_INDENT spaces, ignoring any lines that start with a multiple of OLD_INDENT. Maybe I misread, but that's what I thought he wanted. Did you not see my code comments expressing that very intent? Anyway, it wouldn't be that hard to modify what I gave to do multiple replacement: just add a recursive call. -- - Justin -- http://mail.python.org/mailman/listinfo/python-list
Re: Nested function scope problem
Gerhard Fiedler wrote: On 2006-07-30 09:54:14, Antoon Pardon wrote: Aren't you looking too much at implementation details now? Possibly, but at this point I'm still trying to understand how Python does these things, and what the useful abstraction level is for me. I also still have very little experience how I'll put the things we've been discussing Sorry I've been away from this sub-thread for a while (even though I kinda started it :P). Yes, I'm also wondering what difference this big huge argument makes on how I logically follow Python. Personally, I find this metaphor in Head First Java from O'Reilly Press really helpful for both Python and Java. Before anyone sends me a letter bomb that says Python != Java, let me say this: have phun :P. Anyway, the metaphor goes something like this: variables (for objects, not primitives) are like cups (just wait, it gets better). You can put a remote control IN a cup. The remote control controls a real object on the heap (ie, the data for the object is there). Unfortunately, some of the effect of the metaphor is lost because I cannot reporduce the very nice illustrations which came in the book :P. Other than the fact that you declare variables in Java (going down another letter-bomb-laden slippery slope), which means they stick around even when they have no remote controls, I pretty much think of Python variables the same way: each variable LOGICALLY contains a reference (ie, without regard to what the mechanics are) to some amorphous glob of data, sitting on the heap. Therefore, when I do an assignment, I am simply replacing the reference my variable is holding. According to the metaphor, we are replacing the remote control our cup is holding. If an object is no longer visible (because all the references have disappeared), then it should get garbage collected eventually. But until the magical garbage-collecting angle of death makes is way through the heap, our orphaned objects are PHYSICALLY still there until they are forcefully evicted from memory. Logically, however, they were gone as soon as we lost sight of them. Java aside, My question is this: how will using this metaphor break the way I logically follow Python? here into (Python) practice. While not new to programming, I'm new to Python. AFAIU, one can also build a C++ class hierarchy that with some small limitations in used operators, would have semantics very similar to Python. Would you argue that those using such a C++ class hierarchy would no longer be using variables in C++? Probably not. But for me it's mostly about useful terminology, not necessarily correct terminology. In order to talk about correct terminology, we'd have to use a common definition of variable. This is a term so widely used that I'm not sure there is a useful single definition of it; do you know one? This is another thing I was thinking the entire time I was reading this argument, but I didn't want someone to answer me in a condescending tone on what exactly a variable IS. I guess I should attribute that quote to Bill Clinton :P. In any case, the following doesn't seem to be implementation detail (and rather a part of the language), but it's not really understandable with a C++ concept of variable: a=3 id(a) 3368152 b=a id(b) 3368152 b=4 id(b) 3368140 You don't expect the identity of the variable b to change with a simple assignment from a C/C++ point of view. You also don't expect the identity of a and b to be the same after assigning one to the other. You can create C++ classes that behave like that (you can implement Python in C++ :), but that doesn't mean that you expect C++ language constructs to behave like that. I'm really not comfortable with C, but I disagree. What would you say about this program: #include stdio.h #include stdlib.h #include string.h #define tf(bool) (bool) ? true : false const char * greeting = hello world; int main() { /* These mallocs don't really need to be hear for me to make my point, because as far as I know, what they return is garbage values anyway :P. I just put them there so my pointers are pointing to real objects.*/ char * string = (char *) malloc(sizeof(char)*100); char * letterBomb = (char *) malloc(sizeof(char)*100); strcpy(string, greeting); strcpy(letterBomb, greeting); printf(are we equal? %s\n, tf(strcmp(string, letterBomb) == 0)); printf(are we IDENTICAL? %s\n, tf(string == letterBomb)); printf(sabotage...\n); letterBomb = string; printf(are we identical NOW? %s\n, tf(string==letterBomb)); } Gerhard -- http://mail.python.org/mailman/listinfo/python-list
Re: FOR LOOPS
OriginalBrownster wrote: I am using a class called UploadedFile. I want to create a for loop to itterate through the objects within file name class UploadedFile(SQLObject): filename = StringCol(alternateID=True) abspath = StringCol() uniqueid = IntCol() I'll show you a snippit of the code I am trying to use it in:: zip= [zip.txt] file_path = [myfile.filename for myfile in UploadedFile.select(orderBy=UploadedFile.q.filename)] if kw: for filename in file_path: zip.append(filename) flash('Options selected'+ str(kw) + str(zip)) else: pass When i run this the flash displays all the values for kw...however zip only shows up as zip.txt using the str function. Meaning that the FOR LOOP is not working correctly. Any ideas why this is happening?? perhaps someone could shoe me how to make a proper list for this if this is incorrect. Thank you I'm not really familiar with SQLObject, but are you sure file_path is not empty? Also, a few small comments: 1. zip is a builtin function. I would choose a different name, even though this is not strictly necessary. 2. You can accomplish what you seem to be intending with your loop using list.extend. 3. That's an interesting thing to put in an else case. Why did you do it that way instead of just leaving it out? -- http://mail.python.org/mailman/listinfo/python-list
Re: Html character entity conversion
[EMAIL PROTECTED] wrote: Here is my script: from mechanize import * from BeautifulSoup import * import StringIO b = Browser() f = b.open(http://www.translate.ru/text.asp?lang=ru;) b.select_form(nr=0) b[source] = hello python html = b.submit().get_data() soup = BeautifulSoup(html) print soup.find(span, id = r_text).string OUTPUT: #1087;#1088;#1080;#1074;#1077;#1090; #1087;#1080;#1090;#1086;#1085; -- In russian it looks like: привет питон How can I translate this using standard Python libraries?? -- Pak Andrei, http://paxoblog.blogspot.com, icq://97449800 I'm having trouble understanding how your script works (what would a BeautifulSoup function do?), but assuming your intent is to find character reference objects in an html document, you might try using the HTMLParser class in the HTMLParser module. This class delegates several methods. One of them is handle_charref. It will be called with one argument, the name of the reference, which includes only the number part. HTMLParser is alot more powerful than that though. There may be something more light-weight out there that will accomplish what you want. Then again, you might be able to find a use for all that power :P. -- http://mail.python.org/mailman/listinfo/python-list
Re: Nested function scope problem
Bruno Desthuilliers wrote: Gerhard Fiedler wrote: On 2006-07-25 04:06:24, Steve Holden wrote: Dennis Lee Bieber wrote: On Mon, 24 Jul 2006 17:35:50 -0300, Gerhard Fiedler [EMAIL PROTECTED] declaimed the following in comp.lang.python: It is surprising in the sense that binding seems not to be necessary for read access. It does, I would agree, seem a little counter-intuitive that assignment (or binding) forces the name to be considered local. That's just one of Python's features. Ok... I can live with that, and thanks for the confirmation that it's not only me to feel that this is somewhat surprising :) Since Python has no local variable declaration, there must be a rule to distinguish local names from names living in the enclosing namespaces. The rule is: unless previously declared 'global' (ie module-level) with the appropriate statement, any name bound in the local namespace is local. If declared 'global', it has to exist in the global namespace. This was much more simple to understand when we didn't have nested functions - we mostly had global and local scope. Fact is that we now have nested functions, but still no statement equivalent to 'global' for parent namespaces - with the result that we cannot actually rebind parent's namespace names from within a nested function. But we are still free to modify any mutable object we can access, so the usual workaround for immutable objects is to wrap them in a mutable container (list, dict, etc): def outer(): def _inner(): outer_var[0] = 'dead' outer_var = ['parrot'] print before, outer_var = %s % outer_var _inner() print after, outer_var = %s % outer_var and before you say it: yes, it's a dirty hack. Surprising for me are actually two things: 1- the fact itself, and 2- that term binding, and that whatever it means (I'll have to read more on that, now that I know the term) a binding is the association of a name and a reference to an object in a given namespace. It's different from the common notion of variable, which is usually a symbolic name for a memory address storing a value (like a pointer to an object's address). Wait, I'm not sure I see the difference. Isn't reference ~ C pointer. Are you saying Python variables don't hold references to actual Python objects? That idea has been working well for me so far. is different for read-only and read/write access. What makes the difference is that binding a name to an object in a namespace creates the name in this namespace (unless the name as been declared global, cf above). With the result that, the name existing in the local namespace, it won't be looked up in enclosing namespaces. Neither the Post-It note metaphor nor the pointer explanation address that. Using the Post-It note metaphor, I'm asking myself why the label doesn't get attached to a different box when reading, The normal lookup rule for names is local namespace then enclosing namespaces until top-level (module, aka 'global'), then builtins. Else, you would have to declare as global any module / function / whatever name in each and every function. but only when writing. cf above and below. (Just one of Python's features, I know :) Same thing with the pointer explanation: AFAIK, no language that uses pointers explicitly does something similar (that is, the storage the pointer points to is different depending on whether the pointer gets used for writing and reading, or only for reading). In most languages, you have to explicitly declare local names one way or another. Python takes the opposite route : you have to explicitly declare global names. Since you don't declare local names, binding creates the name if it doesn't already exists in the local namespace. HTH -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: Nested function scope problem
Gerhard Fiedler wrote: On 2006-07-23 14:53:33, danielx wrote: I can't figure out why Josiah's breakLine function won't work either. I know Josiah has had his problem resolved, but I'd still like to know why his func won't work. I'd like to redirect this discussion in that direction, if I may. I think what happens is this (and this may not be expressed in the proper terms for Python): It is possible to read variables from the outer function in the inner function. But when trying to write to them, this causes that same name to be re-defined in the inner function's scope, making it a different variable. Now, in the OP's code, that caused that new variable (with scope of the inner function) to be accessed before anything was assigned to it. One obvious way is to not write to the variables from the outer scope, but rather return a value from the inner function and assign it in the outer function. But it seems there should be a way to be able to write in the inner function to variables that are defined in the outer function. First point: the nested function only have access to names that exists in the enclosing namespace at the time it's defined. Coming from lisp, that doesn't make very much sense, and I'm not sure that's true. If you move the def for addTok bellow the lines that initialize the locals of breakLines, you still get the same problem. The problem there is only secondarily a scope problem. At first it is reading a variable (the inner function scope variable tok) before anything has been assigned to it. Of course, the real problem is the secondary one: that this variable tok is a variable of scope addTok and not of scope breakLine. Second point: a nested function cannot rebind names from the enclosing namespace. Note that in Python, rebinding a name and modifying the object bound to a name are very distinct operations. I'm not sure that's the problem, because when I ran the debugger, the problem is with the line that says if len(tok), not the one bellow it which says tok = . Regardless, my above issue seems to be overriding this one. Yes, but it is the line tok = '' that seems to cause tok to be now a variable of the inner function's scope (rather than the variable tok of breakLine). OHH! Yes, that sounds like it could be it. Wow, to me, that behavior is eXtremely unexpected (there's lisp popping up its ugly head again :P). So you're saying that because an assignment to tok appears later within the def for addTok, that the line if len(tok) won't try to look in enclosing local scopes? (If such things even exist...) Gerhard's reply sounded not so confident. Can we have someone who really knows weigh in on this? Thanks! After some experimentation, I am completely baffeled as to why breakLine won't work. Here is an example of one of the things I did, which I believe exactly mimics what breakLine does: def outer(): ... def inner(): ... if outerLocal: ... return I hear you, 'hello world'. ... else: ... return Come again? ... outerLocal = hello world ... return inner() ... outer() I hear you, 'hello world'. As I said, I believe the line which sets tok should break (quietly), but not the line which tests tok. My experiment seems to confirm this... The line that sets tok causes tok to be a different tok from the outer tok -- in the whole scope of the assignment. Gerhard -- http://mail.python.org/mailman/listinfo/python-list
Re: Which Pyton Book For Newbies?
W. D. Allen wrote: I want to write a retirement financial estimating program. Python was suggested as the easiest language to use on Linux. I have some experience programming in Basic but not in Python. I have two questions: 1. What do I need to be able to make user GUIs for the program, and 2. Which book would be easiest to use to learn Python programming? Thanks, WDA [EMAIL PROTECTED] end I'm sure you will hear this many times, but that's a great choice ;). I really think you'll like Learning Python from O'Reilly Press. The authors claim you can read the book even with no prior programming experience, which seems plausible having read it. Of course, you already have some programming experience, so it should go much more smoothly with you. Good luck finding the right book! -- http://mail.python.org/mailman/listinfo/python-list
Re: Nested function scope problem
Bruno Desthuilliers wrote: Josiah Manson a écrit : I found that I was repeating the same couple of lines over and over in a function and decided to split those lines into a nested function after copying one too many minor changes all over. The only problem is that my little helper function doesn't work! It claims that a variable doesn't exist. If I move the variable declaration, it finds the variable, but can't change it. Declaring the variable global in the nested function doesn't work either. But, changing the variable in the containing scope is the whole purpose of this helper function. I'm new to python, so there is probably some solution I haven't encountered yet. Could you please suggest a nice clean solution? The offending code is below. Thanks. def breakLine(s): Break a string into a list of words and symbols. def addTok(): if len(tok) 0: if tok: An empty sequence evals to False in a boolean context. ls.append(tok) tok = '' I can't figure out why Josiah's breakLine function won't work either. I know Josiah has had his problem resolved, but I'd still like to know why his func won't work. I'd like to redirect this discussion in that direction, if I may. First point: the nested function only have access to names that exists in the enclosing namespace at the time it's defined. Coming from lisp, that doesn't make very much sense, and I'm not sure that's true. If you move the def for addTok bellow the lines that initialize the locals of breakLines, you still get the same problem. Second point: a nested function cannot rebind names from the enclosing namespace. Note that in Python, rebinding a name and modifying the object bound to a name are very distinct operations. I'm not sure that's the problem, because when I ran the debugger, the problem is with the line that says if len(tok), not the one bellow it which says tok = . Regardless, my above issue seems to be overriding this one. Third point : functions modifying their environment this way are usually considered bad form. Again, this is coming from lisp, but I don't see anything wrong with that :P. *** After some experimentation, I am completely baffeled as to why breakLine won't work. Here is an example of one of the things I did, which I believe exactly mimics what breakLine does: def outer(): ... def inner(): ... if outerLocal: ... return I hear you, 'hello world'. ... else: ... return Come again? ... outerLocal = hello world ... return inner() ... outer() I hear you, 'hello world'. As I said, I believe the line which sets tok should break (quietly), but not the line which tests tok. My experiment seems to confirm this... One thing I can understand is why the line tok = in addTok won't work. This is because when Python sees that line, it should create a new local variable in the scope of addTok. Once addTok returns, that variable is lost. That's pretty deep, now that I've thought about it... Here's a possible solution - but note that there are probably much better ways to get the same result... def breakline(line): Break a string into a list of words and symbols. class TokenList(list): def append(self, token): if token: list.append(self, token) return '' tokens = TokenList() token = '' splitters = '?()|:~,' whitespace = ' \t\n\r' specials = splitters + whitespace for char in line: if char in specials: token = tokens.append(token) if char in splitters: tokens.append(char) else: token += char tokens.append(token) return list(tokens) (snip) -- http://mail.python.org/mailman/listinfo/python-list
Re: random shuffles
Boris Borcic wrote: does x.sort(cmp = lambda x,y : cmp(random.random(),0.5)) pick a random shuffle of x with uniform distribution ? Intuitively, assuming list.sort() does a minimal number of comparisons to achieve the sort, I'd say the answer is yes. But I don't feel quite confortable with the intuition... can anyone think of a more solid argumentation ? - BB -- On naît tous les mètres du même monde Someone has already said this, but I'm not sure we can ignore exactly what algorithm we are using. With that in mind, I'll just arbitrarily choose an algorithm to use for analysis. I know you want something that works in N*log(N) where N is the length of the list, but I'm going to ignore that and consider selection sort for the sake of a more solid argument. In that case, you would NOT achieve a uniform distribution. I quote that because I'm going to make up a definition, which I hope corresponds to the official one ;). To me, uniform will mean if we look at any position in the list, element e has 1/N chance of being there. Let e be the element which was in the first position to begin with. What are its chances of being there after being sorted? Well, in order for it to still be there, it would have to survive N rounds of selection. In each selection, it has 1/2 chance of surviving. That means its total chance of survival is 1/(2**N), which is much less than 1/N. QED! *** After writting that down, I thought of an argument for an N*log(N) algorithm, which would cause the resulting list to be uniformly random: tournament sort (I think this is also called binary tree sort). How many rounds does an element have to win in order to come out on top? A number which approaches log2(N). This is like before, except this element doesn't have to survive as many rounds; therefore, it's total chance of coming out on top is 1/(2**log2(N)) == 1/N. Hoorah! *** After considering that, I realized that even if your idea to shuffle a list did work (can't tell because I don't know how Python's sort works), it would not be an optimal way to shuffle a list even though Python uses an N*log(N) sort (at least I hope so :P). This is because you can shuffle in time proportional the the length of the list. You can accomplish this by doing what I will call random selection. It would be like linear selection, except you wouldn't bother checking the head against every other element. When you want to figure out what to put at the head, just pick at random! I suspect this is what Python does in random.shuffle, since it is rather an easy to see it would result in something uniform (I swear I haven't looked at the source code for random.shuffle :P). -- http://mail.python.org/mailman/listinfo/python-list
Re: random shuffles
David G. Wonnacott wrote: From: danielx [EMAIL PROTECTED] Date: 22 Jul 2006 01:43:30 -0700 Boris Borcic wrote: does x.sort(cmp = lambda x,y : cmp(random.random(),0.5)) pick a random shuffle of x with uniform distribution ? ... Let e be the element which was in the first position to begin with. What are its chances of being there after being sorted? Well, in order for it to still be there, it would have to survive N rounds of selection. In each selection, it has 1/2 chance of surviving. That means its total chance of survival is 1/(2**N), which is much less than 1/N. QED! This proof makes sense to me if the sorting algorithm makes a random decision every time it swaps. Couldn't we easily get an n*log(n) shuffle by performing a _single_ mapping of each element in the collection to a pair made up of a random key and its value, and then sorting based on the keys and stripping them out? i.e., in O(n) time, turn 2 clubs, 2 diamonds, 2 hearts, 2 spades, 3 clubs into something like [0.395, 2 clubs], [0.158, 2 diamonds], [0.432, 2 hearts], [0.192, 2 spades], [0.266, 3 clubs] and then in O(n*log(n)) time, sort it into [0.158, 2 diamonds], [0.192, 2 spades], [0.266, 3 clubs], [0.395, 2 clubs], [0.432, 2 hearts] and then strip out the keys again in O(n) time? Or perhaps this has been discussed already and I missed that part? I just joined the list... apologies if this is a repeat. Yes, that would work beautifully. You could use the key argument of list.sort. What we are talking about though, is using the cmp argument. I.e. will list.sort(cmp=lambda:???) be able to give you a shuffle? I think most of us think this depends on what sort algorithm Python uses. You can accomplish this by doing what I will call random selection. It would be like linear selection, except you wouldn't bother checking the head against every other element. When you want to figure out what to put at the head, just pick at random! I suspect this is what Python does in random.shuffle, since it is rather an easy to see it would result in something uniform (I swear I haven't looked at the source code for random.shuffle :P). But, after making the linear selection, don't you still need to use O(log(n)) time to find and remove the item from the collection? I don't know much about Python's internal data structures, but if there's an array in there, you need O(n) time to move up everything after the deleted item; if there's a list, you need O(n) time to find the element you picked at random; if there's a balanced tree, you could find it and delete it in O(log(n)) time... I'm almost sure there's a C array back there as well (well, not techinically an array, but something from malloc), because indexing a Python list is supposed to be fast. It would take constant time to put something at the head. Just swap with the thing that's already there. Since you have to do this swap for each position, it takes time proportional to N. When I originally came up with this idea, I was thinking you would not choose a new head among previously chosen heads. But if you do allow that, I think it will still be uniform. So my original idea was something like this: 1 2 3 4 # ^ head pos stage 0: we need to choose something to put in pos 0. We can choose anything to go there. (swap) 3 2 1 4 #^ head pos stage 1: we need to choose something to put in pos 1. We can choose among things in positions greater than or equal to 1 ie, we may choose among 2 1 4. etc. This is what I meant when I said this would be like linear selection, because once something is in its correct position, it doesn't get moved. But you might also be able to achieve a uniform sort if in stages 1 and up, you are still allowed to choose anything you want to be the head. I'll let someone else figure it out :P. Help me review my undergraduate data structures here -- is there some way to pick each item _exactly_once_ in O(n) time? I think I answered this in the first segment of this post. Let me know if I don't seem clear. Dave Wonnacott -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Bruno Desthuilliers wrote: danielx wrote: Bruno Desthuilliers wrote: danielx wrote: (snip) Obviously, such things would be omitted from your docs, but users also learn by interacting with Python, which is really one of Python's great virtues. When supporting documents aren't sufficient to learn an api (I'm sure this never happens, so just humor me), you can always turn to interactive Python. ...and source code... *shudders* What happened to all the goodness of abstraction? Compared to machine language, Python source code is really abstration. And machine language is an abstraction of pushing electrons around circuits. I'm not sure I see your point, unless it is simply that Python is easier than asm. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Gerhard Fiedler wrote: On 2006-07-20 18:10:21, danielx wrote: When supporting documents aren't sufficient to learn an api (I'm sure this never happens, so just humor me), you can always turn to interactive Python. ...and source code... *shudders* What happened to all the goodness of abstraction? Abstraction as you seem to use it requires complete docs of the interface. Which is what you said you don't have... So the original abstractor broke the abstraction when publishing insufficient docs, not the one who looks into the sources to find out what actually happens. Absolutely. I didn't mean the user was breaking abstraction (let's not blame the victim). I was saying that we should really have more sympathy for him. (This independently of the merits of abstraction.) Gerhard -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
fuzzylollipop wrote: danielx wrote: Bruno Desthuilliers wrote: danielx wrote: At first I was going to post the following: !-- beginning of my original post -- (snip) !-- end of my original post, with ending censored -- but then I tried this: res = Foo.__dict__['func'] res is dan True And it all started to make sense. The surprising thing turned out to be not so surprising: When the expression Foo.func gets evaluated, we get a method which is just a wrapper around dan. Therefore, f is not dan! This is still a little bit of magic, FWIW, the function class implements the descriptor protocol... Here's the magic. which gets me thinking again about the stuff I self-censored. Since the dot syntax does something special and unexpected in my case, unexpected ? Did you ever wondered how the instance or class was passed as first arg when doing method calls ? Not knowing what's going on during method calls is exactly what motivated me to post. why not use some more dot-magic to implement privates? What for ? What makes you think we need language-inforced access restriction ? I knew someone would bring this up. The motivation would not be to provide restriction, but to help maintain clean api's. If you intended for users to use only a subset of the methods in your class, why not help them learn your api by presenting the stuff they can use not along side the stuff they should not? Obviously, such things would be omitted from your docs, but users also learn by interacting with Python, which is really one of Python's great virtues. When supporting documents aren't sufficient to learn an api (I'm sure this never happens, so just humor me), you can always turn to interactive Python. This is exactly what it's there for. If nothing is hidden, a user could be easily mislead to believe he can use a method when he really shouldn't. if you prefix with a single underscore, that tells the user, DON'T MESS WITH ME FROM OUTSIDE! I AM AN IMPLEMENTATION DETAIL! and it gets ommited from all the doc generation if you prefix with a double underscore, then they have to go even FARTHER out of their way to shoot themselves in the foot. Python takes the stance of personal responsiblity when it comes to access control. Which in NO WAY dimishes its robustness or anything else. just read the DailyWTF.com, incompentent people will abuse any language features in any language, and will figure out how to break programatic access control no matter how it is implemented. Matter of fact, Java which in another thread someone was ADAMANT that did not expose private anything from reflection ( and was wrong ) specifically allows you to access all the private members, functions, everything. You just need to tell it to turn all the safeties off. From the api: public void setAccessible(boolean flag) throws SecurityException Set the accessible flag for this object to the indicated boolean value. A value of true indicates that the reflected object should suppress Java language access checking when it is used. A value of false indicates that the reflected object should enforce Java language access checks. Setting the accessible flag in a reflected object permits sophisticated applications with sufficient privilege, such as Java Object Serialization or other persistence mechanisms, to manipulate objects in a manner that would normally be prohibited. so anything added to Python to enforce access control would immediately be forced to provide some means to over-ride the checks for pickle and the like. Not to even mention the argument that it would break crap loads of existing code base. Sigh. I TOTALLY realize that Python works by politeness and not enforcement. I think you are misinterpreting why I think this would be a good idea. My concern is not with control, but with convenience. My suggestion was that privates would only be invisible if you use the dot syntax (ie if you are an external user); they would not be invisible altogether (they would still be in __dict__ with no name games). One problem which was brought up about this was that self.meth and outsider.meth would have to be interpretted differently. I suspect (but I haven't finished my reading assignment :P) that you could find a good way around this. With respect to breaking stuff. I'm not sure why that would be necessary. If current code does not say any member is private, everything that was visible before (ie everything) would still be visible after. Last thing. You mentioned that auto doc generation omits underscore-prefixed and name mangled members. dir on the other hand does not. Maybe this suggests only a minor future improvement. -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Bruno Desthuilliers wrote: danielx a écrit : Bruno Desthuilliers wrote: danielx wrote: Bruno Desthuilliers wrote: danielx wrote: (snip) Obviously, such things would be omitted from your docs, but users also learn by interacting with Python, which is really one of Python's great virtues. When supporting documents aren't sufficient to learn an api (I'm sure this never happens, so just humor me), you can always turn to interactive Python. ...and source code... *shudders* What happened to all the goodness of abstraction? Compared to machine language, Python source code is really abstration. And machine language is an abstraction of pushing electrons around circuits. I'm not sure I see your point, unless it is simply that Python is easier than asm. Python is very hi-level, and very often well-written Python code is it's own better documentation. Yes, Python is very easy to read, but who's supposed to be reading it? Maintainers or users? I'm really against code acting as its own documentation. Of course the code is authoritative, but should we really EXPECT it to serve as a reference to users?? Appearantly, this view puts me in the minority... -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Bruno Desthuilliers wrote: Antoon Pardon wrote: On 2006-07-21, fuzzylollipop [EMAIL PROTECTED] wrote: danielx wrote: (snip) if you prefix with a single underscore, that tells the user, DON'T MESS WITH ME FROM OUTSIDE! I AM AN IMPLEMENTATION DETAIL! Personnaly I don't like this convention. To bad for you. It isn't clear enough. Oh yes ? Suppose I am writing my own module, I use an underscore, to mark variables which are an implementation detail for my module. Now I need to import an other module in my module and need access to an implementation variable from that module. So now I have variables with an underscore which have two different meanings: 1) This is an implemantation detail of this module, It is the users of my module who have to be extra carefull using it. 2) This is an implemantation detail of the other module, I should be extra carefull using it. Either you imported with the from othermodule import * form (which you shouldn't do), and you *don't* have the implementation of othermodule, or your used the import othermodule form, in which case it's pretty obvious which names belongs to othermodule. Have any other, possibly valid, reason ? And I find variable starting or ending with an underscore ugly. :-) Too bad for you. Choose another language then... PHP, Perl, Ruby ?-) Too bad for you: While you have a valid point that this contention is really just arbitrary (just like all conventions), could we be a little gentler? Personally, I don't think it looks very good either, but you just have to deal with it if you're going to use the language properly. -- http://mail.python.org/mailman/listinfo/python-list
Re: question about what lamda does
Bruno Desthuilliers wrote: danielx wrote: (snip) Python's lambda really can't be as powerful as Lisp's because Python does not have expressions that do case analysis (this is not lambda's fault, of course ;). The reason is that you really want to put each case on its own set of lines. This enhances readability at the expense of terseness. Since Python's statements are terminated by a newline, it would be rather awkward to have a kind of expression where good style calls for it to be spread out accross multiple lines. You can try to simulate these kinds expressions using into a list or dictionary, but this becomes rather messy. I think the only way to get this done properly is to use eval. For example: def recursiveFunction(args): ... # do stuff... choices = { True:0, False:recurisveFunction(newArgs) } return eval( choices[predicate] ) Why do you want to use eval here ? The reason that you need eval is that you want to prevent any cases from being executed until you decide which one you want. What about: def recursiveFunction(args): ... # do stuff... ... # that defines 'newArgs' and 'predicate' of course ... return (recursiveFunction, lambda x: 0)[predicate](newArgs) Sure, that works, but don't take things so literally. For instance, if you have a bunch of cases, you might not way to apply the same set of arguments to all of them. Also, let's not get distracted from the main point about how doing case analysis in an expression is ugly, making lambda's weaker in Python than in the language which inspired them. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Bruno Desthuilliers wrote: danielx wrote: Bruno Desthuilliers wrote: danielx wrote: (snip) which gets me thinking again about the stuff I self-censored. Since the dot syntax does something special and unexpected in my case, unexpected ? Did you ever wondered how the instance or class was passed as first arg when doing method calls ? Not knowing what's going on during method calls is exactly what motivated me to post. !-) Ok, so now you have to read about descriptors, __getattribute__ and __setattr__. why not use some more dot-magic to implement privates? What for ? What makes you think we need language-inforced access restriction ? I knew someone would bring this up. Indeed. The motivation would not be to provide restriction, but to help maintain clean api's. If you intended for users to use only a subset of the methods in your class, why not help them learn your api by presenting the stuff they can use not along side the stuff they should not? Obviously, such things would be omitted from your docs, but users also learn by interacting with Python, which is really one of Python's great virtues. When supporting documents aren't sufficient to learn an api (I'm sure this never happens, so just humor me), you can always turn to interactive Python. ...and source code... *shudders* What happened to all the goodness of abstraction? This is exactly what it's there for. If nothing is hidden, a user could be easily mislead to believe he can use a method when he really shouldn't. Single leading underscore means implementation, don't touch or you're on your own. I'll remember that. I had forgotten what the convention was for labeling things do not touch. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: question about what lamda does
[EMAIL PROTECTED] wrote: Hey there, i have been learning python for the past few months, but i can seem to get what exactly a lamda is for. What would i use a lamda for that i could not or would not use a def for ? Is there a notable difference ? I only ask because i see it in code samples on the internet and in books. thanks for any clarity sk hehe. Lambda's are kind of a sensative subject for pythoners who come from Lisp. Guido being more of a C guy doesn't really like them, and thought they should be removed in py3k. Last time I checked, he was reconsidering because of public outcry, presumably from the Lisp crowd. The standard reason for getting rid of it is anywhere you need a lambda, you can use a def. In addition to what has been said here, there is another one small difference between lambda's and functions, which is that when you use def, the object gets a name: def foo(): pass ... foo function foo at 0x009D8230 # ^ foo knows its own name bar function foo at 0x009D8230 # ^ see ;) Whereas, a lambda has no name; it's anonymous: spam = lambda: 1 spam function lambda at 0x009D80F0 # ^ spam has an identity crisis ;) Many people who do not come from Lisp do not understand what the use of a lambda is (and I have no idea what the purpose of having a name is). Even people who do question whether it belongs in Python. In Lisp, lambda's are the way things get done, because you can calculate anything using just defines and expressions. This style does not fit Python very well, since we do things using statements. Python's lambda really can't be as powerful as Lisp's because Python does not have expressions that do case analysis (this is not lambda's fault, of course ;). The reason is that you really want to put each case on its own set of lines. This enhances readability at the expense of terseness. Since Python's statements are terminated by a newline, it would be rather awkward to have a kind of expression where good style calls for it to be spread out accross multiple lines. You can try to simulate these kinds expressions using into a list or dictionary, but this becomes rather messy. I think the only way to get this done properly is to use eval. For example: def recursiveFunction(args): ... # do stuff... choices = { True:0, False:recurisveFunction(newArgs) } return eval( choices[predicate] ) The reason that you need eval is that you want to prevent any cases from being executed until you decide which one you want. This stay of execution is accomplished by wrapping quotes around our expressions. This example illustrates why we really need this kind of behavior, because without it, we would fall into an infinite loop. Even if it were safe to evaluate all cases, it's a big waste of time to do so. Lastly, I think there is also a performance concern for certain uses of lambda (correct me if I'm wrong). Say you have an expression with a lambda in it where you could have used a def. Every time you evaluate that expression, you have to construct a new lambda object, which takes time. If you had used a def instead, you could hav avoided having to construct multiple times. -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Bruno Desthuilliers wrote: danielx wrote: At first I was going to post the following: !-- beginning of my original post -- (snip) !-- end of my original post, with ending censored -- but then I tried this: res = Foo.__dict__['func'] res is dan True And it all started to make sense. The surprising thing turned out to be not so surprising: When the expression Foo.func gets evaluated, we get a method which is just a wrapper around dan. Therefore, f is not dan! This is still a little bit of magic, FWIW, the function class implements the descriptor protocol... Here's the magic. which gets me thinking again about the stuff I self-censored. Since the dot syntax does something special and unexpected in my case, unexpected ? Did you ever wondered how the instance or class was passed as first arg when doing method calls ? Not knowing what's going on during method calls is exactly what motivated me to post. why not use some more dot-magic to implement privates? What for ? What makes you think we need language-inforced access restriction ? I knew someone would bring this up. The motivation would not be to provide restriction, but to help maintain clean api's. If you intended for users to use only a subset of the methods in your class, why not help them learn your api by presenting the stuff they can use not along side the stuff they should not? Obviously, such things would be omitted from your docs, but users also learn by interacting with Python, which is really one of Python's great virtues. When supporting documents aren't sufficient to learn an api (I'm sure this never happens, so just humor me), you can always turn to interactive Python. This is exactly what it's there for. If nothing is hidden, a user could be easily mislead to believe he can use a method when he really shouldn't. (snip) BTW, I am aware of Python's name mangling feature. Name mangling is mainly here to protect from accidental overridding. The convention for implementation attributes is single-leading-underscore. -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Leif K-Brooks wrote: danielx wrote: This is still a little bit of magic, which gets me thinking again about the stuff I self-censored. Since the dot syntax does something special and unexpected in my case, why not use some more dot-magic to implement privates? Privates don't have to be entirely absent from Klass.__dict__ (which would make Python not introspective); they can just be invisible when using the dot-syntax. You can do this now, kind of: class Foo(object): ... x = property() ... def doStuffWithX(self): ... self.__dict__['x'] = 123 ... print self.__dict__['x'] ... bar = Foo() bar.doStuffWithX() 123 bar.x Traceback (most recent call last): File stdin, line 1, in ? AttributeError: unreadable attribute If you're proposing that self.x and bar.x should give different results, then that's quite a bit more magic than property() and methods use. They Yes, I had not considered that very carefully... both use the descriptor API; for more information on that, read http://python.org/download/releases/2.2.3/descrintro/. Let me finish reading that before I get back to your point. -- http://mail.python.org/mailman/listinfo/python-list
Re: function v. method
Duncan Booth wrote: danielx wrote: Foo.func = dan# -- Appearantly, something magical happens here, because... Foo.func unbound method Foo.dan f = Foo.func f is dan # -- things begins to look suprising here. False ismethod(f) True Imagine my surprise. Why would Python do this? Nothing magical happens at the point you said. The assignment is just an assignment and you saw that the function was stored unchanged when you looked in the class's dictionary. The magic happens when you access a member of a class or an instance. If the value is a descriptor then its __get__ method is called. Roughly speaking, Foo.func is equivalent to: Foo.__dict__['func'].__get__(None, Foo) unbound method Foo.dan Python does this so that it can support other descriptor types such as property, classmethod, staticmethod. You can see this happening if you define your own descriptor: class MyDesc(object): def __get__(self, *args): print __get__ called, args return None d = MyDesc() Foo.oops = d Foo.oops __get__ called (None, class __main__.Foo at 0x00B3F930) http://docs.python.org/ref/descriptor-invocation.html has a description of this. Although it claims Note that descriptors are only invoked for new style objects or classes (ones that subclass object() or type()). the descriptor mechanism is partially implemented for old style classes. Several aspects of descriptors don't work properly though in old-style classes which is one reason why you should always use new-style classes. Privates don't have to be entirely absent from Klass.__dict__ (which would make Python not introspective); they can just be invisible when using the dot-syntax. You could implement that using a data descriptor, but if you are going to prevent access to your private variables using the dot operator, then your code is going to look pretty silly with a lot of references to self.__dict__['theprivate'] which doesn't gain anything in readability over self.__theprivate. I believe you are talking about the same thing as Leif, but I can't quite tell. I'll need to read your paper as well :P. -- http://mail.python.org/mailman/listinfo/python-list
Re: Accessors in Python (getters and setters)
Bruno Desthuilliers wrote: ZeD wrote: Bruno Desthuilliers wrote: I decided to change the name of an attribute. Problem is I've used the attribute in several places spanning thousands of lines of code. If I had encapsulated the attribute via an accessor, I wouldn't need to do an unreliable and tedious search and replace find and grep are usually mostly reliable for this kind of tasks. you mean sed :) No, I meant find and grep. sed 's/oldName/newName/g' oldFile newFile Yeah, fine - as long as your pretty sure the same name is not used in other contexts in any of the source files... -- bruno desthuilliers python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')]) I think that was the original point about find/replace: it can be really hard to automate a name change, because changes might occur that you didn't intend; whereas, doing things by hand lacks consistency. My solution is to use emacs' query-replace (which you can invoke with M-%). It will find quicly and accurately, but I ultimately hold the key to whether something gets replaced or not. -- http://mail.python.org/mailman/listinfo/python-list
function v. method
At first I was going to post the following: !-- beginning of my original post -- I just discovered the inspect module, which contains the isfunction and ismethod functions. For some reason, I used to be under the impression that Python methods are no different from Python functions. Naturally, I wondered why both of these needed to exist (I also later discovered the isroutine function). So I started to experiment at prompt. Here's what I did: from inspect import * def dan(): pass ... ismethod(dan) False isfunction(dan) True class Foo: ... def meth(self): pass ... m = Foo.meth m unbound method Foo.meth ismethod(m) True Foo.func = dan# -- Appearantly, something magical happens here, because... Foo.func unbound method Foo.dan f = Foo.func f is dan # -- things begins to look suprising here. False ismethod(f) True Imagine my surprise. Why would Python do this? !-- end of my original post, with ending censored -- but then I tried this: res = Foo.__dict__['func'] res is dan True And it all started to make sense. The surprising thing turned out to be not so surprising: When the expression Foo.func gets evaluated, we get a method which is just a wrapper around dan. Therefore, f is not dan! This is still a little bit of magic, which gets me thinking again about the stuff I self-censored. Since the dot syntax does something special and unexpected in my case, why not use some more dot-magic to implement privates? Privates don't have to be entirely absent from Klass.__dict__ (which would make Python not introspective); they can just be invisible when using the dot-syntax. BTW, I am aware of Python's name mangling feature. -- http://mail.python.org/mailman/listinfo/python-list