[Tutor] What does 'Bind Return Key' do?

2019-04-29 Thread Matthew Polack
Hi,

We're learning Python with PySimpleGUi and have used this example program...

https://github.com/PySimpleGUI/PySimpleGUI/blob/master/ProgrammingClassExamples/Win10%20versions/1d%20PSG%20(named%20input%20keys%20and%20catch%20errors).py


There is a mystery command that says:

[sg.ReadButton('Submit', bind_return_key = False)]]

If I change this 'Bind_Return_Key' value from False to True...or in fact
delete it entirely, it appears to make do difference whatsoever to the
functioning of the program that I can see...

Could someone explain what the purpose of this could be? I'm guessing it
has to have a reason to be there!

Thanks!

-- 
**Disclaimer: *Whilst every attempt has been made to ensure that material 
contained in this email is free from computer viruses or other defects, the 
attached files are provided, and may only be used, on the basis that the 
user assumes all responsibility for use of the material transmitted. This 
email is intended only for the use of the individual or entity named above 
and may contain information that is confidential and privileged. If you are 
not the intended recipient, please note that any dissemination, 
distribution or copying of this email is strictly prohibited. If you have 
received this email in error, please notify us immediately by return email 
or telephone +61 3 5382 2529** and destroy the original message.*
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Help request ERROR installing beautifulsoup

2019-04-29 Thread Dr. Luca T
Hi,
i'm new in python, i tried to install beautifulsoup but i had back this error:

ERROR: Complete output from command python setup.py egg_info:
ERROR: Traceback (most recent call last):
  File "", line 1, in 
  File 
"C:\Users\Luca\AppData\Local\Temp\pip-install-u6zd808q\beautifulsoup\setup.py", 
line 22
print "Unit tests have failed!"
  ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean 
print("Unit tests have failed!")?

ERROR: Command "python setup.py egg_info" failed with error code 1 in 
C:\Users\Luca\AppData\Local\Temp\pip-install-u6zd808q\beautifulsoup\

I use windows 10, python 3.7.3 and a minipc with 32-bit technology inside, can 
you help me telling me where i'm wrong please? 🙂

Thanks.

Luca Tartufari


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] feedparser in python

2019-04-29 Thread nathan tech
Hello everyone,

Most recently, I have started work using feedparser.

I noticed, almost straight away, it's a  bit slow.

For instance:

     url="http://feeds.bbci.co.uk/news/rss.xml";

     f1=feedparser.parse(url)


On some feeds, this can take a few seconds, on the talk python to me 
feed, it takes almost 10!

This, obviously, is not ideal when running a program which checks for 
updates every once in a while. Talk about slow!


I tried using etag, and modified, but none of the feeds seem to ever 
have them!

Similarly, this doesn't seem to work:

     f2=feedparser.parse(url, f.headers["date"])

What am I doing wrong?

Any help appreciated.

A greatly frustrated Nate


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help request ERROR installing beautifulsoup

2019-04-29 Thread Peter Otten
Dr. Luca T wrote:

> Hi,
> i'm new in python, i tried to install beautifulsoup but i had back this
> error:
> 
> ERROR: Complete output from command python setup.py egg_info:
> ERROR: Traceback (most recent call last):
>   File "", line 1, in 
>   File
>   "C:\Users\Luca\AppData\Local\Temp\pip-install-
u6zd808q\beautifulsoup\setup.py",
>   line 22
> print "Unit tests have failed!"
>   ^
> SyntaxError: Missing parentheses in call to 'print'. Did you mean
> print("Unit tests have failed!")?
> 
> ERROR: Command "python setup.py egg_info" failed with error code 1 in
> C:\Users\Luca\AppData\Local\Temp\pip-install-u6zd808q\beautifulsoup\
> 
> I use windows 10, python 3.7.3 and a minipc with 32-bit technology inside,
> can you help me telling me where i'm wrong please? 🙂

Try installing bs4 instead of beautifulsoup to get a version that works with 
Python 3.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What does 'Bind Return Key' do?

2019-04-29 Thread Peter Otten
Matthew Polack wrote:

> Hi,
> 
> We're learning Python with PySimpleGUi and have used this example
> program...
> 
> 
https://github.com/PySimpleGUI/PySimpleGUI/blob/master/ProgrammingClassExamples/Win10%20versions/1d%20PSG%20(named%20input%20keys%20and%20catch%20errors).py
> 
> 
> There is a mystery command that says:
> 
> [sg.ReadButton('Submit', bind_return_key = False)]]
> 
> If I change this 'Bind_Return_Key' value from False to True...or in fact
> delete it entirely, it appears to make do difference whatsoever to the
> functioning of the program that I can see...
> 
> Could someone explain what the purpose of this could be? I'm guessing it
> has to have a reason to be there!

With

bind_return_key=True

hitting the  key has the same effect as clicking on the [Submit] 
button.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help request ERROR installing beautifulsoup

2019-04-29 Thread Alan Gauld via Tutor
On 28/04/2019 17:11, Dr. Luca T wrote:
^
> SyntaxError: Missing parentheses in call to 'print'. Did you mean 
> print("Unit tests have failed!")?
> 

> I use windows 10, python 3.7.3 ...

The problem is you are running python 2 code using python 3.
You need to find a python 3 version of your package.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] feedparser in python

2019-04-29 Thread Alan Gauld via Tutor
On 29/04/2019 01:26, nathan tech wrote:

> Most recently, I have started work using feedparser.

I've never heard of it let alone used it so there may
be another forum where you can get specific answers.
But let me ask...

> I noticed, almost straight away, it's a  bit slow.

How do you measure slow? What speed did you expect?
What other xml parsers have you tried? etree for example?
How much faster was it compared to feedparser?

> For instance:
> 
>      url="http://feeds.bbci.co.uk/news/rss.xml";
>      f1=feedparser.parse(url)

So it looks like the parer is doing more than just
parsing it is also fetching the data over the net.
How long does that take? Could it be a slow connection
or server?

Can you try parsing a feed stored on the local
machine to eliminate that portion of the work?
Is it much faster? If so its the network causing the issue.

> On some feeds, this can take a few seconds, on the talk python to me 
> feed, it takes almost 10!

How big is the feed? If its many megabytes then 10s might
not be too bad.

> This, obviously, is not ideal when running a program which checks for 
> updates every once in a while. Talk about slow!

When I talk about "sloow" I'm thinking about
something that takes a long time relative to how long
it would take me manually. If downloading and parsing
these feeds by hand would take you 5 minutes per feed
then 10s is quite fast...

But if parsing by hand takes 30s then 10s would indeed
be slw.

> Similarly, this doesn't seem to work:
> 
>      f2=feedparser.parse(url, f.headers["date"])

define "doesn't work"?
Does the PC crash? Does it not fetch the data?
Does it fail to find "date"?
Do you get an error message - if so what?

> What am I doing wrong?

No idea, you haven't given us enough information.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help request ERROR installing beautifulsoup

2019-04-29 Thread Mats Wichmann
On 4/29/19 1:44 AM, Alan Gauld via Tutor wrote:
> On 28/04/2019 17:11, Dr. Luca T wrote:
> ^
>> SyntaxError: Missing parentheses in call to 'print'. Did you mean 
>> print("Unit tests have failed!")?
>> 
> 
>> I use windows 10, python 3.7.3 ...
> 
> The problem is you are running python 2 code using python 3.
> You need to find a python 3 version of your package.
> 

You definitely want beautifulsoup4, not just because the version 3 one
doesn't work with Python 3, but also because the authors tell you not to
use it:

"This package is OBSOLETE. It has been replaced by the beautifulsoup4
package. You should use Beautiful Soup 4 for all new projects."

By the way, if you are using pip to install, it is recommended to use it
through the Python interpreter you intend to use.  Since you're on
Windows, hopefully you've let your install set up the Python Launcher
and then it would look like:

py -m pip install beautifulsoup4


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] feedparser in python

2019-04-29 Thread Mats Wichmann
On 4/28/19 6:26 PM, nathan tech wrote:
> Hello everyone,
> 
> Most recently, I have started work using feedparser.
> 
> I noticed, almost straight away, it's a  bit slow.
> 
> For instance:
> 
>      url="http://feeds.bbci.co.uk/news/rss.xml";
> 
>      f1=feedparser.parse(url)
> 
> 
> On some feeds, this can take a few seconds, on the talk python to me 
> feed, it takes almost 10!
> 
> This, obviously, is not ideal when running a program which checks for 
> updates every once in a while. Talk about slow!
> 
> 
> I tried using etag, and modified, but none of the feeds seem to ever 
> have them!
> 
> Similarly, this doesn't seem to work:
> 
>      f2=feedparser.parse(url, f.headers["date"])
> 
> What am I doing wrong?
> 
> Any help appreciated.
> 
> A greatly frustrated Nate

This is just an aside... programs which depend on fetching things from
the Web are candidates for various advanced programming techniques.

One is to not write synchronously, where you ask for some data, process
the data, and present results, as if everything happened instantly.
Instead various techniques like using callbacks, or multiple threads, or
multiprocessing, or Python's asynchronous facilities can be employed.
Documentation for several of those techniques use web communications as
their examples :)  In other words, think of writing your code so other
work can happen while waiting for a particular response (for example
firing off requests to other feeds), and thing of how your update
checking can happen in the background so the data is there when you want
to look at it.

Another is when you write your unit tests, mock the responses from the
internet servers so your tests don't suffer the same delays as
interactive use of the program will see.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] self.name is calling the __set__ method of another class

2019-04-29 Thread Arup Rakshit
Hi,

In the following code, class attributes name and email is set to the instances 
of NonBlank.

class NonBlank:
def __init__(self, storage_name):
self.storage_name = storage_name

def __set__(self, instance, value):
if not isinstance(value, str):
raise TypeError("%r must be of type 'str'" % self.storage_name)
elif len(value) == 0:
raise ValueError("%r must not be empty" % self.storage_name)
instance.__dict__[self.storage_name] = value

class Customer:
name = NonBlank('name')
email = NonBlank('email')

def __init__(self, name, email, fidelity=0):
self.name = name
self.email = email
self.fidelity = fidelity

def full_email(self):
return '{0} <{1}>'.format(self.name, self.email)

if __name__ == '__main__':
cus = Customer('Arup', 99)

Running this code throws an error:

Traceback (most recent call last):
  File 
"/Users/aruprakshit/python_playground/pycon2017/decorators_and_descriptors_decoded/customer.py",
 line 25, in 
cus = Customer('Arup', 99)
  File 
"/Users/aruprakshit/python_playground/pycon2017/decorators_and_descriptors_decoded/customer.py",
 line 18, in __init__
self.email = email
  File 
"/Users/aruprakshit/python_playground/pycon2017/decorators_and_descriptors_decoded/customer.py",
 line 7, in __set__
raise TypeError("%r must be of type 'str'" % self.storage_name)
TypeError: 'email' must be of type 'str'
Process terminated with an exit code of 1

Now I am not getting how the __set__() method from NonBlank is being called 
inside the __init__() method. Looks like some magic is going on under the hood. 
Can anyone please explain this how self.name and self.email assignment is 
called the __set__ from NonBlank? What is the name of this concept?


Thanks,

Arup Rakshit
a...@zeit.io



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] self.name is calling the __set__ method of another class

2019-04-29 Thread Steven D'Aprano
On Mon, Apr 29, 2019 at 11:25:51PM +0530, Arup Rakshit wrote:

> Now I am not getting how the __set__() method from NonBlank is being 
> called inside the __init__() method. Looks like some magic is going on 
> under the hood. Can anyone please explain this how self.name and 
> self.email assignment is called the __set__ from NonBlank? What is the 
> name of this concept?


I haven't read your code in detail, but it sounds like the Descriptor 
protocol. Descriptors are used "under the hood" by Python to implement 
methods, classmethod, staticmethod and property, among others, and are 
considered an advanced technique (only slightly less advanced than 
metaclasses).

https://docs.python.org/3/howto/descriptor.html

If you are *not* intentionally trying to write a custom descriptor, you 
should not use a __set__ method. (Perhaps you meant __setitem__?)

In general, you should treat all dunder (Double UNDERscore) methods as 
private to Python, and only implement those that you need. Don't use 
them for your own purposes.


-- 
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] self.name is calling the __set__ method of another class

2019-04-29 Thread Arup Rakshit

On 29/04/19 11:40 PM, Steven D'Aprano wrote:

On Mon, Apr 29, 2019 at 11:25:51PM +0530, Arup Rakshit wrote:


Now I am not getting how the __set__() method from NonBlank is being
called inside the __init__() method. Looks like some magic is going on
under the hood. Can anyone please explain this how self.name and
self.email assignment is called the __set__ from NonBlank? What is the
name of this concept?


I haven't read your code in detail, but it sounds like the Descriptor
protocol. Descriptors are used "under the hood" by Python to implement
methods, classmethod, staticmethod and property, among others, and are
considered an advanced technique (only slightly less advanced than
metaclasses).

https://docs.python.org/3/howto/descriptor.html

If you are *not* intentionally trying to write a custom descriptor, you
should not use a __set__ method. (Perhaps you meant __setitem__?)

In general, you should treat all dunder (Double UNDERscore) methods as
private to Python, and only implement those that you need. Don't use
them for your own purposes.


I really didn't write that code by myself. The day I'll you will not see 
me here everyday :) . I was watching a PyCon video 
https://youtu.be/81S01c9zytE?t=8172 where the author used this code. But 
his explanation is not clear to me. The main problem is that the guy who 
was recorded it far away from the projector, so what speaker were 
showing there is not clear. So thought to ask here as usual. Because I 
felt so lost with this trick.


--
Thanks,

Arup Rakshit

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] self.name is calling the __set__ method of another class

2019-04-29 Thread Steven D'Aprano
On Tue, Apr 30, 2019 at 12:47:02AM +0530, Arup Rakshit wrote:

> I really didn't write that code by myself. The day I'll you will not see 
> me here everyday :) . I was watching a PyCon video 
> https://youtu.be/81S01c9zytE?t=8172 where the author used this code. But 
> his explanation is not clear to me. The main problem is that the guy who 
> was recorded it far away from the projector, so what speaker were 
> showing there is not clear. So thought to ask here as usual. Because I 
> felt so lost with this trick.

Okay, the short, SIMPLIFIED (and therefore inaccurate) summary of 
descriptors:

Descriptors are the "magic" used by Python whenever it does an attribute 
lookup. When you do any sort of attribute lookup or assignment:

x = spam.eggs

spam.eggs = value

Python looks at spam and spam's class for an attribute called "eggs", 
and if that attribute is an object with a __set__ or __get__ method, it 
calls that method:

x = spam.eggs
=> x = spam.eggs.__get__()

spam.eggs = value
=> spam.eggs.__set__(value)

For the gory details of what *precisely* happens, see the Howto Guide:

https://docs.python.org/3/howto/descriptor.html


Python has a few common descriptors built in:

- ordinary methods
- classmethod
- staticmethod
- property

Apart from staticmethod, they're all pretty common in code. But writing 
your own custom descriptors is fairly rare. I've only done it once, in 
25+ years of using Python.


-- 
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What does 'Bind Return Key' do?

2019-04-29 Thread Mike Barnett
You'll find it discussed in a couple of places in the PySimpleGUI documentation.

For example, this was written about it under the Button Element section of the 
docs:
--
The ENTER key :
The ENTER key is an important part of data entry for windows. There's a long 
tradition of the enter key being used to quickly submit windows. PySimpleGUI 
implements this by tying the ENTER key to the first button that closes or reads 
a window.

The Enter Key can be "bound" to a particular button so that when the key is 
pressed, it causes the window to return as if the button was clicked. This is 
done using the bind_return_key parameter in the button calls. 
If there are more than 1 button on a window, the FIRST button that is of type 
Close window or Read window is used. First is determined by scanning the 
window, top to bottom and left to right.
--

When questions like this arise on PySimpleGUI, I recommend pulling up the docs 
and pressing Control-F to do a search.



@mike

-Original Message-
From: Matthew Polack  
Sent: Sunday, April 28, 2019 4:49 AM
To: tutor@python.org
Subject: [Tutor] What does 'Bind Return Key' do?

Hi,

We're learning Python with PySimpleGUi and have used this example program...

https://github.com/PySimpleGUI/PySimpleGUI/blob/master/ProgrammingClassExamples/Win10%20versions/1d%20PSG%20(named%20input%20keys%20and%20catch%20errors).py


There is a mystery command that says:

[sg.ReadButton('Submit', bind_return_key = False)]]

If I change this 'Bind_Return_Key' value from False to True...or in fact delete 
it entirely, it appears to make do difference whatsoever to the functioning of 
the program that I can see...

Could someone explain what the purpose of this could be? I'm guessing it has to 
have a reason to be there!

Thanks!

--
**Disclaimer: *Whilst every attempt has been made to ensure that material 
contained in this email is free from computer viruses or other defects, the 
attached files are provided, and may only be used, on the basis that the user 
assumes all responsibility for use of the material transmitted. This email is 
intended only for the use of the individual or entity named above and may 
contain information that is confidential and privileged. If you are not the 
intended recipient, please note that any dissemination, distribution or copying 
of this email is strictly prohibited. If you have received this email in error, 
please notify us immediately by return email or telephone +61 3 5382 2529** and 
destroy the original message.*

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] feedparser in python

2019-04-29 Thread nathan tech
Hi there,

After reading your email, I did some further investigation,

I first did this test:

     import feedparser

     import time

     def tim(url):

  k=time.time()

  feedparser.parse(url)

  return time.time()-k

The results were as follows:

     tim( a url): 2.9 seconds

     tim(the downoaded file(: 1.8 seconds


That tells me that roughly 1.1 seconds is network related, fair enough.

I admit, I've not tried etree, as I was specificly working with RSS 
feeds but will aim to do so soon.

My specific problem here is that, everywhere  when I look on how to 
check to see if an rss feed has been updated, without downloading the 
entire thing again, they all say use ETAG and Modified, but my feeds 
never, have them.

I've tried feeds from several sources, and none have them in the http 
header.

To that end, that is why I mentioned in the previous email about .date, 
because that seemed the most likely, but even that failed.

My goal is thus:

1, download a feed to the computer.

2. Occasionally, check the website to see if the donloaded feed is out 
of date if it is, redownload it.

Ultimately, I want to complete step 2 without downloading the *entire* 
feed again, though.


I did think about using threading for this, for example:

program loads,

user sees downloaded feed data only, in the background, the program 
checks for updates on each feed, and the user may see them gradually 
start to update.

This would work, in that execution would not fail at any time, but it 
seems... clunky, to me I suppose? And rather data jheavy for the end 
user, especially if, as you suggest, a feed is 10 MB in size.


Furthering to that, how many threads is safe?

Should I have my main thread, plus 4 feeds updating at once? 5? 2?

Any help is appreciated.

Thanks

Nate

On 29/04/2019 08:43, Alan Gauld via Tutor wrote:
> On 29/04/2019 01:26, nathan tech wrote:
>
>> Most recently, I have started work using feedparser.
> I've never heard of it let alone used it so there may
> be another forum where you can get specific answers.
> But let me ask...
>
>> I noticed, almost straight away, it's a  bit slow.
> How do you measure slow? What speed did you expect?
> What other xml parsers have you tried? etree for example?
> How much faster was it compared to feedparser?
>
>> For instance:
>>
>>       url="http://feeds.bbci.co.uk/news/rss.xml";
>>       f1=feedparser.parse(url)
> So it looks like the parer is doing more than just
> parsing it is also fetching the data over the net.
> How long does that take? Could it be a slow connection
> or server?
>
> Can you try parsing a feed stored on the local
> machine to eliminate that portion of the work?
> Is it much faster? If so its the network causing the issue.
>
>> On some feeds, this can take a few seconds, on the talk python to me
>> feed, it takes almost 10!
> How big is the feed? If its many megabytes then 10s might
> not be too bad.
>
>> This, obviously, is not ideal when running a program which checks for
>> updates every once in a while. Talk about slow!
> When I talk about "sloow" I'm thinking about
> something that takes a long time relative to how long
> it would take me manually. If downloading and parsing
> these feeds by hand would take you 5 minutes per feed
> then 10s is quite fast...
>
> But if parsing by hand takes 30s then 10s would indeed
> be slw.
>
>> Similarly, this doesn't seem to work:
>>
>>       f2=feedparser.parse(url, f.headers["date"])
> define "doesn't work"?
> Does the PC crash? Does it not fetch the data?
> Does it fail to find "date"?
> Do you get an error message - if so what?
>
>> What am I doing wrong?
> No idea, you haven't given us enough information.
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] self.name is calling the __set__ method of another class

2019-04-29 Thread Cameron Simpson

On 29Apr2019 23:25, Arup Rakshit  wrote:
In the following code, class attributes name and email is set to the 
instances of NonBlank.


class NonBlank:
   def __init__(self, storage_name):
   self.storage_name = storage_name

   def __set__(self, instance, value):
   if not isinstance(value, str):
   raise TypeError("%r must be of type 'str'" % self.storage_name)
   elif len(value) == 0:
   raise ValueError("%r must not be empty" % self.storage_name)
   instance.__dict__[self.storage_name] = value

class Customer:
   name = NonBlank('name')
   email = NonBlank('email')

   def __init__(self, name, email, fidelity=0):
   self.name = name
   self.email = email
   self.fidelity = fidelity

   def full_email(self):
   return '{0} <{1}>'.format(self.name, self.email)

if __name__ == '__main__':
   cus = Customer('Arup', 99)

Running this code throws an error:

Traceback (most recent call last):
 File 
"/Users/aruprakshit/python_playground/pycon2017/decorators_and_descriptors_decoded/customer.py",
 line 25, in 
   cus = Customer('Arup', 99)
 File 
"/Users/aruprakshit/python_playground/pycon2017/decorators_and_descriptors_decoded/customer.py",
 line 18, in __init__
   self.email = email
 File 
"/Users/aruprakshit/python_playground/pycon2017/decorators_and_descriptors_decoded/customer.py",
 line 7, in __set__
   raise TypeError("%r must be of type 'str'" % self.storage_name)
TypeError: 'email' must be of type 'str'
Process terminated with an exit code of 1

Now I am not getting how the __set__() method from NonBlank is being 
called inside the __init__() method. Looks like some magic is going on 
under the hood. Can anyone please explain this how self.name and 
self.email assignment is called the __set__ from NonBlank? What is the 
name of this concept?


As Steven has mentioned, it looks like NonBlank is a descriptor, which 
defined here:


 https://docs.python.org/3/glossary.html#term-descriptor

So NonBlank has a __set__ method. The above text says:

  When a class attribute is a descriptor, its special binding behavior 
  is triggered upon attribute lookup. Normally, using a.b to get, set 
  or delete an attribute looks up the object named b in the class 
  dictionary for a, but if b is a descriptor, the respective descriptor 
  method gets called.


So when your new Customer object runs its __init_ method and goes:

 self.name = name

Since Customer.name is a descriptor, this effectively calls:

 NonBlank.__set__(self, name)

which in turn does some type and value checking and then directly 
modifies self.__dict__ to effect the assignment.


So yes, some magic is occurring - that is what the Python dunder methods 
are for: to provide the mechanism for particular magic actions.


Descriptors are rarely used directly, however the @property decorator is 
quite ommon, where you define methodlike functions which look like 
attributes. Untested example:


 class Foo:
   def __init__(self):
 self.timestamp = time.time()
   @property
   def age(self):
 return time.time() - self.timestamp

which you'd access directly as:

 foo = Foo()
 print("age =", foo.age)

@property arranges this using descriptors: in the example above it 
arranges that the class "age" attribute is a descriptor with a __get__ 
method.


Cheers,
Cameron Simpson 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor