Re: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers?
Am 05.08.2017 um 06:14 schrieb Ben Finney: Thomas Güttler writes: The underlaying question is: Imangine you are a newcomer. A newcomer is in a tough position when it comes to packaging and distributing Python code, especially the command-line programs. There has been significant progress on this in recent years. The Setuptools third-party library is a lot saner, the inclusion of ‘pip’ in standard installs makes it much broader in scope. But *not* in the standard library today, it's true. You need a guide like 'if unsure do x'. With other words: What is the sane default choice? There isn't a good answer to that question, today. The best answer today is: Read the guides from the Python Packaging Authority, and stay abreast of developments because this continues to change. Maybe eventually the ongoing work of the PyPA will be settled enough that it can update the standard library Distutils. But not today. You say that there isn't a good answer to that question, today. For me the question was: setup.py "script" vs "console_scripts" ? I found this: https://packaging.python.org/tutorials/distributing-packages/#console-scripts You say that there isn't a good answer to that question, today. I can't follow. Why is "the sane default is 'use console_scripts entry-point in setup.py'" not a good answer? Regards, Thomas Güttler -- Thomas Guettler http://www.thomas-guettler.de/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod?
On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote: > py3: class MyClass: > ... def my_method(): > ... print('This is my_method in MyClass!') > ... > py3: class MyOtherClass: > ... @staticmethod > ... def my_other_method(): > ... print('This is my_other_method in MyOtherClass!') > ... > py3: MyClass.my_method() > This is my_method in MyClass! > py3: MyOtherClass.my_other_method() > This is my_other_method in MyOtherClass! A small comment: since the methods have different names, there's no reason why they couldn't both be in the same class. It is hard to see the distinction between an ordinary method and a static method from this example. What you are seeing is, by accident, the equivalent of just writing: def my_method(): print('This is my_method in MyClass!') outside of the class and calling the bare function. Notice that despite the name, my_method is not *actually* usable as a method. It has no "self" parameter. > I see no difference in result, whether I use the @staticmethod decorator or > not. Indeed you would not, because you are calling MyClass.my_method, directly from the class object. If you created an instance first, and then called the methods, you would see a big difference! obj = MyClass() obj.my_method() # fails with TypeError, as there is no "self" parameter while the staticmethod would succeed. So what's going on here? When you call MyClass.my_method, Python looks up my_method on the class object, equivalent to: thing = getattr(MyClass, 'my_method') before calling thing(), which then prints the message. This is where is gets complex... Python performs some special magic when you look up attributes, according to "the descriptor protocol". Don't worry about how it works -- think of it as black magic for now. But the bottom line is, if the look up returns something like a string or an int or a list, no descriptor magic happens, but if it returns a function (something you created with "def"), something not far removed from this happens: # (instance) method descriptor if thing is a function: if the source was a class # like "MyClass.method": # This was different in Python 2. return thing, unchanged else: # source was an instance, "MyClass().method" wrap thing in a method object that receives "self" return the method object Why does it bother? Because that way Python can automatically fill in the instance as "self". Example: today we write: s = "Hello world!" t = s.upper() But without this method magic, or something similar, we would have to write: s = "Hello world!" t = str.upper(s) # need to manually provide "self" or even: s = "Hello world!" t = s.upper(s) in order for the upper() method to receive the instance s as the "self" parameter. Despite the name, your example "my_method" isn't a method and doesn't require "self". If you try to pass one in, you get a TypeError because the function doesn't take any arguments at all. But normally methods need to know what instance they are working on, in other words, they need to know "self". So when you call MyClass.my_method, calling from the class, Python just gives you the raw function object, unchanged. Normally that means you would need to provide "self" yourself. This is called an "unbound method", it's unbound because it doesn't know what instance to work on. Example: str.upper is the equivalent of an unbound method. It is incomplete, because it doesn't know what string to uppercase. You have to provide one for it to work on: str.upper("spam") But if you call directly from an instance, Python knows what string to use as "self", and you don't need to do any more: "spam".upper() Unbound methods have their uses. In Python 2, they were actual custom method objects, but in Python 3 it was decided that this was pointless and instead the bare function is returned instead. But conceptually, the base function is an unbound method. So normal methods convert a function to a method which automatically provides "self", but only if called from the instance (self). Otherwise they return the function, which needs you to manually provide self. In your example, by accident (I assume?) you forgot to include "self", so the fact that no self was provided didn't stop the function from working. Now, how about class methods? Class methods are just like ordinary (instance) methods, except instead of "self", they receive the class object as first parameter. There aren't many good examples of class methods, and so they aren't common. But here's one: dict.fromkeys Most dict methods (update, pop, popitem, clear, etc.) need to know which specific dict to work on. But fromkeys is different: it does not care what instance you use. Both of these will work exactly the same: {}.fromkeys(['one', 'two', 'three']) {100: 'A', 200: 'B'
Re: [Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod?
I feel like I have gazed into a crystal clear pool, apparently shallow, with many interesting objects (Pun intended!) on the pool floor. Interested in these beautiful things, I jump in to grab one for close-up study only to find that the pool is much, ... , much deeper (> 1 boB-height) than it appeared. And alas! I don't know how to swim! On Mon, Aug 7, 2017 at 8:36 AM, Steven D'Aprano wrote: > On Sun, Aug 06, 2017 at 06:35:10PM -0500, boB Stepp wrote: > >> py3: class MyClass: >> ... def my_method(): >> ... print('This is my_method in MyClass!') >> ... >> py3: class MyOtherClass: >> ... @staticmethod >> ... def my_other_method(): >> ... print('This is my_other_method in MyOtherClass!') >> ... >> py3: MyClass.my_method() >> This is my_method in MyClass! >> py3: MyOtherClass.my_other_method() >> This is my_other_method in MyOtherClass! > > A small comment: since the methods have different names, there's no > reason why they couldn't both be in the same class. As I did not know exactly where I was going with these exploratory examples, I thought I would keep things separated in case something surprising developed. Then I could easily compare the two. > It is hard to see the distinction between an ordinary method and a > static method from this example. What you are seeing is, by accident, > the equivalent of just writing: > > def my_method(): > print('This is my_method in MyClass!') > > outside of the class and calling the bare function. Notice that despite > the name, my_method is not *actually* usable as a method. It has no > "self" parameter. I thought that was the whole essence of static methods -- no self parameter. > >> I see no difference in result, whether I use the @staticmethod decorator or >> not. > > Indeed you would not, because you are calling MyClass.my_method, > directly from the class object. If you created an instance first, and > then called the methods, you would see a big difference! Alan pointed out I might want to investigate this. I did and got what you show below. > obj = MyClass() > obj.my_method() # fails with TypeError, as there is no "self" parameter > > while the staticmethod would succeed. > > So what's going on here? > > When you call MyClass.my_method, Python looks up my_method on the class > object, equivalent to: > > thing = getattr(MyClass, 'my_method') > > before calling thing(), which then prints the message. > > This is where is gets complex... Python performs some special magic when > you look up attributes, according to "the descriptor protocol". Don't > worry about how it works -- think of it as black magic for now. But the > bottom line is, if the look up returns something like a string or an int > or a list, no descriptor magic happens, but if it returns a function > (something you created with "def"), something not far removed from this > happens: > > # (instance) method descriptor > if thing is a function: > if the source was a class # like "MyClass.method": > # This was different in Python 2. > return thing, unchanged > else: # source was an instance, "MyClass().method" > wrap thing in a method object that receives "self" > return the method object > > Why does it bother? Because that way Python can automatically fill in > the instance as "self". [snip] > > Despite the name, your example "my_method" isn't a method and doesn't > require "self". If you try to pass one in, you get a TypeError because > the function doesn't take any arguments at all. But normally methods > need to know what instance they are working on, in other words, they > need to know "self". Question(s): While something like "my_method" can't be called from an object instance, it can be called on the class. Are there use cases where this behavior is actually desired? If wrapped with "@staticmethod" then there are two ways of calling the method, using objects or using the class. Is there some reason not to use the "ClassName.a_static_method()" syntax? Are there intended uses for doing this? > So when you call MyClass.my_method, calling from the class, Python just > gives you the raw function object, unchanged. Normally that means you > would need to provide "self" yourself. This is called an "unbound > method", it's unbound because it doesn't know what instance to work on. [snip] > Unbound methods have their uses. In Python 2, they were actual custom > method objects, but in Python 3 it was decided that this was pointless > and instead the bare function is returned instead. But conceptually, the > base function is an unbound method. > > So normal methods convert a function to a method which automatically > provides "self", but only if called from the instance (self). Otherwise > they return the function, which needs you to manually provide self. > > In your example, by accident (I assume?) ... No, on purpose. I was just playing around to see what would o
Re: [Tutor] setup.py "script" vs "console_scripts" Was: if __name__=='main' vs entry points: What to teach new comers?
Thomas Güttler writes: > Why is "the sane default is 'use console_scripts entry-point in > setup.py'" not a good answer? Because third-party Setuptools is required for entry points, which means entry points cannot be a default choice. It may well be a good choice for many cases. But that's a different matter from it being a good *default* choice; it can only be a default choice if it's in the standard library. -- \ “The best in us does not require the worst in us: Our love of | `\ other human beings does not need to be nurtured by delusion.” | _o__) —Sam Harris, at _Beyond Belief 2006_ | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] How does len() compute length of a string in UTF-8, 16, and 32?
py3: s = 'Hello!' py3: len(s.encode("UTF-8")) 6 py3: len(s.encode("UTF-16")) 14 py3: len(s.encode("UTF-32")) 28 How is len() getting these values? And I am sure it will turn out not to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm ... -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?
boB Stepp writes: > How is len() getting these values? By asking the objects themselves to report their length. You are creating different objects with different content:: >>> s = 'Hello!' >>> s_utf8 = s.encode("UTF-8") >>> s == s_utf8 False >>> s_utf16 = s.encode("UTF-16") >>> s == s_utf16 False >>> s_utf32 = s.encode("UTF-32") >>> s == s_utf32 False So it shouldn't be surprising that, with different content, they will have different length:: >>> type(s), len(s) (, 6) >>> type(s_utf8), len(s_utf8) (, 6) >>> type(s_utf16), len(s_utf16) (, 14) >>> type(s_utf32), len(s_utf32) (, 28) What is it you think ‘str.encode’ does? -- \ “In the long run, the utility of all non-Free software | `\ approaches zero. All non-Free software is a dead end.” —Mark | _o__)Pilgrim, 2006 | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?
On Mon, Aug 7, 2017 at 9:44 PM, boB Stepp wrote: > py3: s = 'Hello!' > py3: len(s.encode("UTF-8")) > 6 > py3: len(s.encode("UTF-16")) > 14 > py3: len(s.encode("UTF-32")) > 28 > > How is len() getting these values? And I am sure it will turn out not > to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm First, make sure you know exactly what is having its length checked. In each of those cases, you're not checking the length of the string, `s`, you're checking the length of the string `s` encoded in various encodings (try each of those lines without the 'len' part). Next, take a dive into the wonderful* world of Unicode: https://nedbatchelder.com/text/unipain.html https://www.youtube.com/watch?v=7m5JA3XaZ4k Hope this helps, -- Zach ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?
On 07Aug2017 21:44, boB Stepp wrote: py3: s = 'Hello!' py3: len(s.encode("UTF-8")) 6 py3: len(s.encode("UTF-16")) 14 py3: len(s.encode("UTF-32")) 28 How is len() getting these values? And I am sure it will turn out not to be a coincidence that 2 * (6 + 1) = 14 and 4 * (6 + 1) = 28. Hmm The result of str.encode is a bytes object with the specified encoding of the original text. Your sample string contains only ASCII characters, which encode 1-to-1 in UTF-8. So as you might expect, your UTF-8 encoding is 6 bytes. The others have a slight twist. Let's see: Python 3.6.1 (default, Apr 24 2017, 06:17:09) [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> s = 'Hello!' >>> s.encode() b'Hello!' >>> s.encode('utf-16') b'\xff\xfeH\x00e\x00l\x00l\x00o\x00!\x00' >>> s.encode('utf-32') b'\xff\xfe\x00\x00H\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00!\x00\x00\x00' The utf-8 encoding (the default) is as you would expect. The UTF-16 and UTF-32 encodings encode code points into 2 and 4 byte sequences as you might expect. Unlike the UTF-8 encoding, however, it is necessary to to know whether these byte sequences are big-endian (most significant byte first) or little-endian (least significant byte first). The machine I'm on here is writing big endian UTF-16 and UTF-32. As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This is because each encoding has a leading byte order marker to indicate the big endianness or little endianness. For big endian data that is \xff\xfe; for little endian data it would be \xfe\xff. Cheers, Cameron Simpson (formerly c...@zip.com.au) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How does len() compute length of a string in UTF-8, 16, and 32?
On Tue, Aug 8, 2017 at 3:20 AM, Cameron Simpson wrote: > > As you note, the 16 and 32 forms are (6 + 1) times 2 or 4 respectively. This > is because each encoding has a leading byte order marker to indicate the big > endianness or little endianness. For big endian data that is \xff\xfe; for > little endian data it would be \xfe\xff. To avoid encoding a byte order mark (BOM), use an "le" or "be" suffix, e.g. >>> 'Hello!'.encode('utf-16le') b'H\x00e\x00l\x00l\x00o\x00!\x00' Sometimes a data format includes the byte order, which makes using a BOM redundant. For example, strings in the Windows registry use UTF-16LE, without a BOM. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor