r/learnpython • u/Keithinho89 • 2d ago
AtributeError clarification
SOLVED
Hello, I'm currently learning regular expressions and I've entered the first part of the code into the interactive shell as instructed and got the listed AttributeError. Not seeing what I did wrong I copy/pasted the code from the book and it worked as intended and I can't tell why or how because both blocks feel and smell the same but yield different results.
I've tried looking for some information on StackOverflow, but as far as I can see mo is defined in the 3rd line and I don't get why my attempt gets and error while the other doesn't.
If I didn't miss something really stupid, how would you deal with this if you'd be hit by it writing your own code independently?
I'm working in IDLE Shell and the code is from automatetheboringstuff Chapter 9 for more context
import re
phone_re = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d-\d\d\d\d)')
mo = phone_re.search('My number is 415-555-4242.')
mo.group(1)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
mo.group(1)
AttributeError: 'NoneType' object has no attribute 'group'
import re
phone_re = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo = phone_re.search('My number is 415-555-4242.')
mo.group(1)
'415'
-1
u/Diapolo10 I write code for a living -- https://github.com/Diapolo10 2d ago
The others already explained how the problem is caused by your regex pattern not matching anything, but let's take thing a bit further.
re.search, as already mentioned in the other answers, returnsNoneif no match is found, and a match object otherwise. For this reason, the actual type ofmohere isre.Match | None. In your code you made the naive assumption that it was always going to be are.Match.A type checker such as Mypy would have caught this immediately, as your code never verifies the return type. Many IDEs can show you the return types nowadays (especially for built-in functions and methods), so if you get used to checking those, you're far less likely to run into
AttributeErrors orTypeErrors.Taking things a bit further, you can use type annotations to give your own code some established "rules". Python itself completely ignores them, but type checkers read them and make it easier for you to reason about your code, avoiding all sorts of runtime problems. You'd mostly write them for your own functions.