Live data from Hacker News

Python and the Principle of Least Astonishment

lucumr.pocoo.org

31–40 of 53 posts

Re: Python and the Principle of Least Astonishment

#31
post #30

"I was quite fond of Raymond Hettinger's talk about what makes Python unique because he showed a bunch of small examples that almost exclusively used the good parts of the standard library and hardly any user written logic." Is this talk available anywhere?

I'm not certain but I think it was one of these http://ep2011.europython.eu/conference/speakers/raymond-hett...

Maybe this http://ep2011.europython.eu/conference/talks/what-makes-pyth...

Re: Python and the Principle of Least Astonishment

#32

Earlier quoted context omitted.

If I have the following code: @auth_required def some_view(): pass And later I decide to change that decorator to be parameterized: @auth_required("basic") def some_view(): pass I have now created a massive amount of pain for myself if I decide to define auth_required() such that it defaults its argument to "basic", unless I force people to call it as @auth_required(), because of the differing callable signatures. So…

> Some people feel @auth_required() is ugly. That's all. The biggest issue here is backwards compatibility. Nowadays I just make a separate decorator that accepts arguments and keep the old one around unchanged. I learned my lesson :)

You may also use a simple wrapper to create decorators which would automatically define @decorator and @decorator().

Re: Python and the Principle of Least Astonishment

#33

Differentiating properties and methods from internal methods is as simple as using another char, like dots and colons. So box.length would not be the same as box:length, that way you could assign all names you want without fear of collision. Poor choices in language design will always haunt you til the end of times. That being said, python is my favorite language right now and the only complain I have is about unders…

Would you mean this to be a namespace which only the Python implementation could access? For example, if the protocol "it:next" is added (which is equivalent to next(it)) then is there any way to support that syntax in an older version? With next() as a builtin it's easy; try: next except NameError, and in case of exception, implement the function yourself. But if I can't implement it myself then there's no good migration path.

With your particular choice of ":", then what would "d={a:length()}" be? Currently it's a 1-element set. What would "words[middle:length()]" do?

Re: Python and the Principle of Least Astonishment

#34
post #33

Differentiating properties and methods from internal methods is as simple as using another char, like dots and colons. So box.length would not be the same as box:length, that way you could assign all names you want without fear of collision. Poor choices in language design will always haunt you til the end of times. That being said, python is my favorite language right now and the only complain I have is about unders…

Would you mean this to be a namespace which only the Python implementation could access? For example, if the protocol "it:next" is added (which is equivalent to next(it)) then is there any way to support that syntax in an older version? With next() as a builtin it's easy; try: next except NameError, and in case of exception, implement the function yourself. But if I can't implement it myself then there's no good migr…

"is there any way to support that syntax in an older version"

Nop, that is exactly what I meant with decisions haunting you forever. You better start a new language than radically change the current implementation.

With regard to my particular choice of ':' there are three solutions:

1. pick any of the 100k unicode chars for internal methods but imperative is to differentiate them to freely use attributes and methods as pleased.

2. force the compiler and the coder to disambiguate the possible same use as internal method: first assign then use n=a:length(), d={n}

3. design the language to use .. as slicer and {a=b} as dictionary assignment.

Again, we are talking about design decisions for a new language, not to change the core of an existing language which is not an easy task. That is exactly why language design is not an exact science an very few make it to stardom.

Re: Python and the Principle of Least Astonishment

#35
post #10

For extra fun.... a = 5 def print_a(): print a # Prints 5 print_a() def print_and_assign_a(): print a a = 2 # raises UnboundLocalError print_and_assign_a() class PrintOnInitSet(set): def __init__(self, *args, **kwargs): print "init!" set.__init__(self, *args, **kwargs) # Creates a PrintOnInitSet and prints "init!" a = PrintOnInitSet([1,2]) # Creates a PrintOnInitSet and prints "init!" b = PrintOnInitSet([3,4]) # Crea…

Well, your first example makes sense. It ensures you're always referring to the same-scoped 'a' throughout your function. FWIW if you said 'global a' at the start of 'print_and_assign_a', Python wouldn't have a problem: >>> a = 5 >>> def print_and_assign_a(): ... global a ... print(a) ... a = 2 ... >>> print_and_assign_a() 5 >>> print_and_assign_a() 2 Your second example, however, seems to show an implementation deta…

> Should "a = set([1,2])" be equivalent to "a = set(); a.add(1); a.add(2)"?

Why should it be? Adding elements one-by-one is slow and shouldn't be forced on the language model level.

Re: Python and the Principle of Least Astonishment

#36
post #13

It's a bit dated, but the Python Cookbook does a great job of teaching you practical examples of Python if you already know other languages and want to quickly grok what is "pythonic." It starts with string crunching and hits just about every other general sysadmin use case, covering most of the standard library along the way.

May I know why it is a bit dated? because I'm thinking to buy the book and the year is 2005, which is good enough for me since 2005 means Python 2.5 at least (or even more).

Re: Python and the Principle of Least Astonishment

#37
post #32

Earlier quoted context omitted.

> Some people feel @auth_required() is ugly. That's all. The biggest issue here is backwards compatibility. Nowadays I just make a separate decorator that accepts arguments and keep the old one around unchanged. I learned my lesson :)

You may also use a simple wrapper to create decorators which would automatically define @decorator and @decorator().

I could also aim with a bazooka at my foot. Been there done that, lesson learned :-)

Re: Python and the Principle of Least Astonishment

#38
post #13

It's a bit dated, but the Python Cookbook does a great job of teaching you practical examples of Python if you already know other languages and want to quickly grok what is "pythonic." It starts with string crunching and hits just about every other general sysadmin use case, covering most of the standard library along the way.

May I know why it is a bit dated? because I'm thinking to buy the book and the year is 2005, which is good enough for me since 2005 means Python 2.5 at least (or even more).

The 2nd edition of Python Cookbook doesn't cover Python 2.5. It covers language features that were there till Python 2.4. (http://oreilly.com/catalog/9780596007973) The 3rd edition of Python Cookbook is expected to appear by end of this year. http://dabeaz.blogspot.com/2010/12/oreilly-python-cookbook-p...

Re: Python and the Principle of Least Astonishment

#40

So... Python has len() because it would be too hard to standardize on .len(). Any by the way, len() calls .__len__(), on which we have standardized. Got it.

The better explanation is that there are a series of fallback actions for all of the top level functions that delegate to the .__whatever__ methods.

For example, if you write a class that quacks like a collection that has a length (it implements .__len__) Python can use that to get a value for bool() even if you didn't implement .__nonzero__.

Post reply on HN