@JHB17 @fatrat A good way to explore this is to try it out. Create a script, let’s call it test.py and include the following variables:

some_variable = 10
_another_variable = 20
__yet_another_one = 30

Then try from test import * in the REPL/Console. You’ll see that only some_variable is public so only that variable is imported.

But now, add the following at the top of the script:

__all__ = ["_another_variable", "__yet_another_one"]

and try from test import * in a new REPL/Console (not the same one as before, as the old version is already imported there)

@fatrat In fact, here’s what the official Python style guide, PEP 8, says about the matter:

“Wildcard imports (from import *) should be avoided, as they make it unclear which names are present in the namespace, confusing both readers and many automated tools."

peps.python.org/pep-0008/#impo

@fatrat Yes, you do find that a lot, but that doesn’t make it good. Many things are a matter of preference, but this is one of those things where it’s now generally considered best to avoid.

You can see what’s imported by accessing the __all__ property, so:

tkinter.__all__

If a module doesn’t have this defined, then all the non private names will be imported. But if a module has __all__ defined, then only what’s included in __all__ will be defined

@JHB17 @fatrat Although in general, it’s always best to avoid from ... import *

@erikdesmedt @out_of_cheese Correct, and in the standard Python REPL, the underscore stores the last value, so you don't need to assign it, either

Weird Python line of the day:

>>> [10, 20, 15, 12, 9][_]
[20, 15]

How can you achieve this?

Note: this is not something you’ll want to do in real code, just a Python curiosity!

@fatrat from … import * doesn’t import everything. The module’s author can decide what’s included.

But note that it’s generally considered bad practice to use from … import * as it dumps lots of stuff into the main namespace. It is safer to keep namespaces separate

Work in progress - An Offside Rule Quiz using Python’s turtle

Will aim to get it done in the next few days… (will write it up as an article, too)

For those who don’t follow football (that’s soccer for some around the world), the offside rule is one of those “notorious” rules that not everyone gets.

This is a great resource for teachers who are eager to teach Python. Teaching Python teachingpython.fm/ #python #edutooter #edtech @edutooters

There are often heated arguments, often with many holding “absolutist” positions, on various topics in . However, as with other areas of life, it’s the more nuanced pragmatic view that (should) prevail.

Let’s take static and dynamic typing. There are reasons why not all leading languages use either one or the other. They’re different tools for different jobs.

If you need to prioritise safety in production code: static typing may be your choice.

If you want to prioritise prototyping speed and writing code rapidly, including by programmers who don’t just program but use coding as part of other professional skills, dynamic typing options may be better.

It’s all about using the right mindset for the right language. If someone is used to coding in C++, say, and tries to write Python code in the same way they write C++, that can (and will) lead to problems! The same is true the other way round, too, of course.

Take duck typing in languages such as : that’s a mindset–prioritising what an object can do rather than what it is. Once you get it, and you think about whether something is a sequence or an iterator rather than a list or string, say, then you’re better placed to code in Python

There’s no “this is the better one”, instead, there’s “this is the better one for this application”

@lewischuang thank you. My philosophy is guided by my experience with teaching technical subjects, first teaching Optics to optometry undergrads, and then years of teaching coding to people of all ages (including kids). I think we all have our own styles of teaching. There’s no good or bad, it’s whatever works best for each learner.

One of my (many) 2023 plans is to add finishing touches to ThePythonCodingBook.com and make it available in some other format, too:

• ebook only
• self-published book
• published via a publisher

My preference is the latter but publishers shy away from beginners’ books…

I’d need to spend time carefully pitching to them why I think it’s different from other books. Not sure I can justify time to do that

More thinking needed

In the meantime, the content is all there for beginners to enjoy, and many have done just that

thepythoncodingbook.com/what-p

@CGM Not all instances have the same limits

@brwillems A big part of the answer is memory management. A generator doesn’t store all the values in memory, it fetches them or creates them as and when they’re required.

Here are two scenarios: you’re reading data from a large data set stored outside of your program (let’s say a large CSV). A generator allows you to represent the “whole data set” in your program, but only needs memory for one item at a time.

Or, you have a large set of data stored in memory, but want to get lots of subsets of it - all the names starting with P in a large list of names, all those 5 letters long, and so on. Each subset can be a generator which uses the same data set (the original one) without duplicating memory

One thing that many find very confusing when they first learn about generators is that once they’re exhausted they’re, erm, exhausted.

Eh?!

Let’s see what this means with an example. Let’s start with a list, first:

numbers = [item for item in range(10)]

# Loop through numbers
for number in numbers:
print(number)

# And let's loop one more time…
for number in numbers:
print(number)

We’ve used a list comprehension to create a list of numbers–it’s not the most exciting list you’ll see, but it will do here

You’re them looping through the list twice, printing out the values each time

Here’s the output from this code:

0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9

I did say it’s not an exciting list. I know!

The numbers are printed out twice. Of course they are, since you’ve repeated the loop twice

Let’s see what happens with a generator instead of a list:

# Notice that we've now made this a generator
numbers = (item for item in range(10))

# Loop through numbers
for number in numbers:
print(number)

# And let's loop one more time…
for number in numbers:
print(number)

Notice how we’re now using parentheses (round brackets) instead of square brackets when creating numbers

This creates a generator

If you print(type(numbers)) you’ll get:
<class 'generator'>

and if you print(numbers):
<generator object <genexpr> at 0x103309ff0>

So, what’s the output from the two for loops?

Let’s find out:

0
1
2
3
4
5
6
7
8
9

The numbers are only printed out once. The generator was “used up” when you looped through it the first time, so you can’t use it again

Here’s why this happens (very abridged version):

A generator doesn’t store the data within it. Instead, it refers to data which is stored or created elsewhere

So, when you try and fetch the first item in numbers, the generator fetches 0 and it now “knows” it’s taken the first value…

So the next time you need a value from numbers, it will get the second one, and so on…

Once it fetches the last item, there’s nothing left
The generator is exhausted
When you try to fetch another item, there’s nothing there

Think of a generator as single-use

Today for #projects: another hashtag I coined, the #pythonoddity hashtag.

Years ago I decided I was going to try tweeting one "python oddity" (anything that might be a gotcha for a new Python user). I decided to make a hashtag for it: #pythonoddity.

I still collect #python oddities but I don't share them as regularly as I used to. Maybe I should start that hashtag up again here?

Here's a collection of some of my favorite #pythonoddity tweets over the years: twitter.com/i/events/871564334

I was rewatching Star Wars recently (kids are now interested) and it reminded me of (tenuous link warning!) when I decided to explore __copy__() in Python and dive a bit deeper

Anyway, here’s the article for those interested - note the image with Lego storm troopers has been there since I published this article!

thepythoncodingbook.com/2022/0

Some more tree behaviours.

Clicking a node to move the cursor now works.

Labels can now have a 'icon' used to show expand state. You call set allow_expand=False for leaf nodes.

This core functionality will for the base of a tree control to browse a directory.

@MahmutRuzi Same with me. I joined a research group for my PhD which used MATLAB, so I learnt to code using MATLAB

When I set up my own research group years later, I had tons of MATLAB scripts so I got my students to learn and use MATLAB too…

When a colleague suggested using this up and coming language called Python (this was c.2005), I remember thinking, nah, can’t be bothered to re-write all this library in another language.

And after all, licenses weren’t a problem as grant funders paid for them!!

A (lengthy) Mastodon #introduction.

I'm Thomas, a Python Core Developer and Googler from Amsterdam (NL). I'm on the Python Steering Council and the #PSF Board of Directors, and I'm the 3.12/3.13 Release Manager. I hang out on #python on libera (IRC) as well. I also have #cats (#Savannah and #Bengal).

I usually toot/boost about #python, especially #governance and non-profit support of #python. A little thread with examples (and cat pictures at the end)👇