#๐ "Local variable might be referenced before assignment"
67 messages ยท Page 1 of 1 (latest)
@oak vigil
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
def validate_path():
try:
while True:
path = Path(input("Enter the path: "))
except KeyboardInterrupt as e:
print(e)
if not path.is_dir():
print("Please enter a valid path.")
else:
return path
this is the function if it helps
The ctrl+c might happen before anything is inputted to be parsed as path
Meaning path variable might not exist when the line if not path.is_dir() is run...
Just like the warning said - "might be referenced (ie: used) before assignment (ie: before it gets created)"
Oh
if the program crashes... ```py
path = Path(input("Enter the path: "))
^-----------------------^ here
Then it exits before anything is passed to Path, then `path` wouldn't be assigned
Ahhh
So basically if the KeyboardInterrupt happens then my if not condition has nothing to work with
hmm
I believe my try/except placement is wrong then
should i put the except lower ?
If it happens before first input
Because the second one (remember the code is in while True) would already have the previous value
You should explain why you have the infinite loop in the first place...
Well If the input is not a path then I want the user to keep entering a proper path as an input until that succeeds so the function can return "path"
I can highly recommend grabbing a pen and paper and just trying to make a simple decision chart what should happen when. It will be clear where you need the path check and whether you need the KeyboardInterrupt (hint: you do not, it's not an exception you normally want to catch, it closes the program anyways when it's not caught)
Oh, this is not about whether I need it or not.
I just want to practice try/excepts
The chart here would look like:
Take input
Check if it's a dir --yes> return
|
no
V
loop back to taking input
No try/except here
This is not a proper practice then, as it introduces more errors than it solves anything.
Better example would be something that you'd normally catch as an error - e.g. asking for number input and it's not a number
Not KeyboardInterrupt, which is really really not recommended to be caught unless you really really really know what you're doing
Or making a calculator and someone enters 0 as divisor
(bonus points: this actually does number parsing as well before you get to the 0)
Okok. Do you mind if I send the full program here (its not long) and you can give me suggestions where I could use try/excepts then?
No solutions ofc, just pointers where i could use them
I don't think this code will have much of that. Paths are abstract concept - only when you start trying to access somethjng you'll encounter any possible errors (file doesn't exist, or isn't writeable, etc). And pathlib already allows you to check a lot of that stuff without doing stuff that throws an exception - e.g. path.exists()...
I do have access stuff later on where I open files to read them.
(looping through dictionary to catch files with .txt or .log)
Actually Nicky
thank you
you gave me a nice idea to use try/except on
I basically answered my question myself.
Hang on, let me try the "not writable" stuff.
def scan_files_for_errors(file_groups):
line_count = 0
for file in [*file_groups['.txt'], *file_groups['.log']]:
try:
with open(file) as content:
line_count += sum(
1 for line in content
if "error" in line.casefold().split()
)
except PermissionError:
print(f"Skipping {file.name} as there are no permissions.")
return line_count
@supple ember if you dont mind, could you please check this?
This would be correct now, no?
Im trying to open a file and if there is a permission error i throw an exception "PermissionError"
i also saw that some people do:
except Exception as e:
print(e)
The "e" i dont quite understood yet- what exactly does it do?
Does python just pick a default error message? or what exactly happens ?
e is just a named variable that holds the exception object
you can name it however you like instead of e
What would the exception object be ?
whatever you just caught
Oh alright ๐
@main moth since Nicky isnt here right now, could you please check the code above whether I have handled the try/except properly?
I could also do a "not readable" if the content is in a weird, unreadable format or so. Like egypt hyroglyphs
but that means when i open(file) i need to specify the format im opening them in I THINK
not sure
that code will only catch PermissionError, not other types of exceptions
you may want to catch OSError if you want broader handling of I/O errors
Yep exactly.
Only PermissionError ๐ for now.
Ill look into OSError now
since anything can happen when interfacing with the file system, it's often a good idea to handle OSError properly
Okay I've read through OSError, let me quickly rewrite something
def scan_files_for_errors(file_groups):
line_count = 0
for file in [*file_groups['.txt'], *file_groups['.log']]:
try:
with open(file) as content:
line_count += sum(
1 for line in content
if "error" in line.casefold().split()
)
except OSError as e:
if e.errno == errno.ENOENT:
print("No such file or directory")
elif e.errno == errno.EACCES:
print("Permission denied")
else:
print(f"Error: {e}")
return line_count
@main moth
I learned:
OSError is basically a "parent" exception of the "PermissionError" exception (and a few other exceptions).
So instead of throwing the "PermissionError" exception and other exceptions separately, i can use OSError instead as one exception and then specify each one of them in the if conditions.
Is that right?
I would do it differently
Oh
def scan_files_for_errors(file_groups):
line_count = 0
for file in [*file_groups['.txt'], *file_groups['.log']]:
try:
with open(file) as content:
line_count += sum(
1 for line in content
if "error" in line.casefold().split()
)
except PermissionError:
print("Permission denied")
except FileNotFoundError:
print("No such file or directory")
except OSError as e:
print(f"Error: {e}")
return line_count
much more readable this way, wouldn't you agree?
much more readable indeed.
Hmm...
Ohhhh
I think I understand why you have done it this way
You only want to focus on the PermissionError and FileNotFoundError, you specify those two exceptions
and then, as the 3rd exception you said "and anything unexpected i want to throw in the OSError exception"
yes
I think i had basically done the same BUT yours is more readable
yup
and it makes sense this way because exceptions are "executed" in chronological order.
so it makes sense to have the OSError as the "any" in the last position
COol cool, this makes a lot of sense thank you :D
The except blocks are considered in order of appearance, yeah.
(a linter would probably catch if you put them in the wrong order, at least for simple cases like this where there's a clear "wrong order")
Alrighty, thank you for the valuable input everyone!!
Try/except blocks arent too complicated after all - as long as you consider your options and think of what you truly want to test / handle when "obvious" things could go wrong
Will be closing the ticket then. Thank you again ๐
This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.