Local variable referenced before assignment in Python

avatar

Last updated: Apr 8, 2024 Reading time · 4 min

banner

# Local variable referenced before assignment in Python

The Python "UnboundLocalError: Local variable referenced before assignment" occurs when we reference a local variable before assigning a value to it in a function.

To solve the error, mark the variable as global in the function definition, e.g. global my_var .

unboundlocalerror local variable name referenced before assignment

Here is an example of how the error occurs.

We assign a value to the name variable in the function.

# Mark the variable as global to solve the error

To solve the error, mark the variable as global in your function definition.

mark variable as global

If a variable is assigned a value in a function's body, it is a local variable unless explicitly declared as global .

# Local variables shadow global ones with the same name

You could reference the global name variable from inside the function but if you assign a value to the variable in the function's body, the local variable shadows the global one.

accessing global variables in functions

Accessing the name variable in the function is perfectly fine.

On the other hand, variables declared in a function cannot be accessed from the global scope.

variables declared in function cannot be accessed in global scope

The name variable is declared in the function, so trying to access it from outside causes an error.

Make sure you don't try to access the variable before using the global keyword, otherwise, you'd get the SyntaxError: name 'X' is used prior to global declaration error.

# Returning a value from the function instead

An alternative solution to using the global keyword is to return a value from the function and use the value to reassign the global variable.

return value from the function

We simply return the value that we eventually use to assign to the name global variable.

# Passing the global variable as an argument to the function

You should also consider passing the global variable as an argument to the function.

pass global variable as argument to function

We passed the name global variable as an argument to the function.

If we assign a value to a variable in a function, the variable is assumed to be local unless explicitly declared as global .

# Assigning a value to a local variable from an outer scope

If you have a nested function and are trying to assign a value to the local variables from the outer function, use the nonlocal keyword.

assign value to local variable from outer scope

The nonlocal keyword allows us to work with the local variables of enclosing functions.

Had we not used the nonlocal statement, the call to the print() function would have returned an empty string.

not using nonlocal prints empty string

Printing the message variable on the last line of the function shows an empty string because the inner() function has its own scope.

Changing the value of the variable in the inner scope is not possible unless we use the nonlocal keyword.

Instead, the message variable in the inner function simply shadows the variable with the same name from the outer scope.

# Discussion

As shown in this section of the documentation, when you assign a value to a variable inside a function, the variable:

  • Becomes local to the scope.
  • Shadows any variables from the outer scope that have the same name.

The last line in the example function assigns a value to the name variable, marking it as a local variable and shadowing the name variable from the outer scope.

At the time the print(name) line runs, the name variable is not yet initialized, which causes the error.

The most intuitive way to solve the error is to use the global keyword.

The global keyword is used to indicate to Python that we are actually modifying the value of the name variable from the outer scope.

  • If a variable is only referenced inside a function, it is implicitly global.
  • If a variable is assigned a value inside a function's body, it is assumed to be local, unless explicitly marked as global .

If you want to read more about why this error occurs, check out [this section] ( this section ) of the docs.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

  • SyntaxError: name 'X' is used prior to global declaration

book cover

Borislav Hadzhiev

Web Developer

buy me a coffee

Copyright © 2024 Borislav Hadzhiev

How to fix UnboundLocalError: local variable 'x' referenced before assignment in Python

by Nathan Sebhastian

Posted on May 26, 2023

Reading time: 2 minutes

unboundlocalerror local variable 'mid' referenced before assignment

One error you might encounter when running Python code is:

This error commonly occurs when you reference a variable inside a function without first assigning it a value.

You could also see this error when you forget to pass the variable as an argument to your function.

Let me show you an example that causes this error and how I fix it in practice.

How to reproduce this error

Suppose you have a variable called name declared in your Python code as follows:

Next, you created a function that uses the name variable as shown below:

When you execute the code above, you’ll get this error:

This error occurs because you both assign and reference a variable called name inside the function.

Python thinks you’re trying to assign the local variable name to name , which is not the case here because the original name variable we declared is a global variable.

How to fix this error

To resolve this error, you can change the variable’s name inside the function to something else. For example, name_with_title should work:

As an alternative, you can specify a name parameter in the greet() function to indicate that you require a variable to be passed to the function.

When calling the function, you need to pass a variable as follows:

This code allows Python to know that you intend to use the name variable which is passed as an argument to the function as part of the newly declared name variable.

Still, I would say that you need to use a different name when declaring a variable inside the function. Using the same name might confuse you in the future.

Here’s the best solution to the error:

Now it’s clear that we’re using the name variable given to the function as part of the value assigned to name_with_title . Way to go!

The UnboundLocalError: local variable 'x' referenced before assignment occurs when you reference a variable inside a function before declaring that variable.

To resolve this error, you need to use a different variable name when referencing the existing variable, or you can also specify a parameter for the function.

I hope this tutorial is useful. See you in other tutorials.

Take your skills to the next level ⚡️

I'm sending out an occasional email with the latest tutorials on programming, web development, and statistics. Drop your email in the box below and I'll send new stuff straight into your inbox!

Hello! This website is dedicated to help you learn tech and data science skills with its step-by-step, beginner-friendly tutorials. Learn statistics, JavaScript and other programming languages using clear examples written for people.

Learn more about this website

Connect with me on Twitter

Or LinkedIn

Type the keyword below and hit enter

Click to see all tutorials tagged with:

The Research Scientist Pod

Python UnboundLocalError: local variable referenced before assignment

by Suf | Programming , Python , Tips

If you try to reference a local variable before assigning a value to it within the body of a function, you will encounter the UnboundLocalError: local variable referenced before assignment.

The preferable way to solve this error is to pass parameters to your function, for example:

Alternatively, you can declare the variable as global to access it while inside a function. For example,

This tutorial will go through the error in detail and how to solve it with code examples .

Table of contents

What is scope in python, unboundlocalerror: local variable referenced before assignment, solution #1: passing parameters to the function, solution #2: use global keyword, solution #1: include else statement, solution #2: use global keyword.

Scope refers to a variable being only available inside the region where it was created. A variable created inside a function belongs to the local scope of that function, and we can only use that variable inside that function.

A variable created in the main body of the Python code is a global variable and belongs to the global scope. Global variables are available within any scope, global and local.

UnboundLocalError occurs when we try to modify a variable defined as local before creating it. If we only need to read a variable within a function, we can do so without using the global keyword. Consider the following example that demonstrates a variable var created with global scope and accessed from test_func :

If we try to assign a value to var within test_func , the Python interpreter will raise the UnboundLocalError:

This error occurs because when we make an assignment to a variable in a scope, that variable becomes local to that scope and overrides any variable with the same name in the global or outer scope.

var +=1 is similar to var = var + 1 , therefore the Python interpreter should first read var , perform the addition and assign the value back to var .

var is a variable local to test_func , so the variable is read or referenced before we have assigned it. As a result, the Python interpreter raises the UnboundLocalError.

Example #1: Accessing a Local Variable

Let’s look at an example where we define a global variable number. We will use the increment_func to increase the numerical value of number by 1.

Let’s run the code to see what happens:

The error occurs because we tried to read a local variable before assigning a value to it.

We can solve this error by passing a parameter to increment_func . This solution is the preferred approach. Typically Python developers avoid declaring global variables unless they are necessary. Let’s look at the revised code:

We have assigned a value to number and passed it to the increment_func , which will resolve the UnboundLocalError. Let’s run the code to see the result:

We successfully printed the value to the console.

We also can solve this error by using the global keyword. The global statement tells the Python interpreter that inside increment_func , the variable number is a global variable even if we assign to it in increment_func . Let’s look at the revised code:

Let’s run the code to see the result:

Example #2: Function with if-elif statements

Let’s look at an example where we collect a score from a player of a game to rank their level of expertise. The variable we will use is called score and the calculate_level function takes in score as a parameter and returns a string containing the player’s level .

In the above code, we have a series of if-elif statements for assigning a string to the level variable. Let’s run the code to see what happens:

The error occurs because we input a score equal to 40 . The conditional statements in the function do not account for a value below 55 , therefore when we call the calculate_level function, Python will attempt to return level without any value assigned to it.

We can solve this error by completing the set of conditions with an else statement. The else statement will provide an assignment to level for all scores lower than 55 . Let’s look at the revised code:

In the above code, all scores below 55 are given the beginner level. Let’s run the code to see what happens:

We can also create a global variable level and then use the global keyword inside calculate_level . Using the global keyword will ensure that the variable is available in the local scope of the calculate_level function. Let’s look at the revised code.

In the above code, we put the global statement inside the function and at the beginning. Note that the “default” value of level is beginner and we do not include the else statement in the function. Let’s run the code to see the result:

Congratulations on reading to the end of this tutorial! The UnboundLocalError: local variable referenced before assignment occurs when you try to reference a local variable before assigning a value to it. Preferably, you can solve this error by passing parameters to your function. Alternatively, you can use the global keyword.

If you have if-elif statements in your code where you assign a value to a local variable and do not account for all outcomes, you may encounter this error. In which case, you must include an else statement to account for the missing outcome.

For further reading on Python code blocks and structure, go to the article: How to Solve Python IndentationError: unindent does not match any outer indentation level .

Go to the  online courses page on Python  to learn more about Python for data science and machine learning.

Have fun and happy researching!

Share this:

  • Click to share on Facebook (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • Click to share on Pinterest (Opens in new window)
  • Click to share on Telegram (Opens in new window)
  • Click to share on WhatsApp (Opens in new window)
  • Click to share on Twitter (Opens in new window)
  • Click to share on Tumblr (Opens in new window)
  • Python Basics
  • Interview Questions
  • Python Quiz
  • Popular Packages
  • Python Projects
  • Practice Python
  • AI With Python
  • Learn Python3
  • Python Automation
  • Python Web Dev
  • DSA with Python
  • Python OOPs
  • Dictionaries
  • How to Fix - UnboundLocalError: Local variable Referenced Before Assignment in Python
  • Python | Accessing variable value from code scope
  • Access environment variable values in Python
  • Get Variable Name As String In Python
  • How to use Pickle to save and load Variables in Python?
  • Undefined Variable Nameerror In Python
  • How to Reference Elements in an Array in Python
  • Difference between Local Variable and Global variable
  • Unused local variable in Python
  • Unused variable in for loop in Python
  • Assign Function to a Variable in Python
  • JavaScript ReferenceError - Can't access lexical declaration`variable' before initialization
  • Global and Local Variables in Python
  • Pass by reference vs value in Python
  • __file__ (A Special variable) in Python
  • Variables under the hood in Python
  • __name__ (A Special variable) in Python
  • PYTHONPATH Environment Variable in Python
  • Julia local Keyword | Creating a local variable in Julia

UnboundLocalError Local variable Referenced Before Assignment in Python

Handling errors is an integral part of writing robust and reliable Python code. One common stumbling block that developers often encounter is the “UnboundLocalError” raised within a try-except block. This error can be perplexing for those unfamiliar with its nuances but fear not – in this article, we will delve into the intricacies of the UnboundLocalError and provide a comprehensive guide on how to effectively use try-except statements to resolve it.

What is UnboundLocalError Local variable Referenced Before Assignment in Python?

The UnboundLocalError occurs when a local variable is referenced before it has been assigned a value within a function or method. This error typically surfaces when utilizing try-except blocks to handle exceptions, creating a puzzle for developers trying to comprehend its origins and find a solution.

Why does UnboundLocalError: Local variable Referenced Before Assignment Occur?

below, are the reasons of occurring “Unboundlocalerror: Try Except Statements” in Python :

Variable Assignment Inside Try Block

Reassigning a global variable inside except block.

  • Accessing a Variable Defined Inside an If Block

In the below code, example_function attempts to execute some_operation within a try-except block. If an exception occurs, it prints an error message. However, if no exception occurs, it prints the value of the variable result outside the try block, leading to an UnboundLocalError since result might not be defined if an exception was caught.

In below code , modify_global function attempts to increment the global variable global_var within a try block, but it raises an UnboundLocalError. This error occurs because the function treats global_var as a local variable due to the assignment operation within the try block.

Solution for UnboundLocalError Local variable Referenced Before Assignment

Below, are the approaches to solve “Unboundlocalerror: Try Except Statements”.

Initialize Variables Outside the Try Block

Avoid reassignment of global variables.

In modification to the example_function is correct. Initializing the variable result before the try block ensures that it exists even if an exception occurs within the try block. This helps prevent UnboundLocalError when trying to access result in the print statement outside the try block.

Below, code calculates a new value ( local_var ) based on the global variable and then prints both the local and global variables separately. It demonstrates that the global variable is accessed directly without being reassigned within the function.

In conclusion , To fix “UnboundLocalError” related to try-except statements, ensure that variables used within the try block are initialized before the try block starts. This can be achieved by declaring the variables with default values or assigning them None outside the try block. Additionally, when modifying global variables within a try block, use the `global` keyword to explicitly declare them.

Please Login to comment...

Similar reads.

  • Python Errors
  • Python Programs

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

[SOLVED] Local Variable Referenced Before Assignment

local variable referenced before assignment

Python treats variables referenced only inside a function as global variables. Any variable assigned to a function’s body is assumed to be a local variable unless explicitly declared as global.

Why Does This Error Occur?

Unboundlocalerror: local variable referenced before assignment occurs when a variable is used before its created. Python does not have the concept of variable declarations. Hence it searches for the variable whenever used. When not found, it throws the error.

Before we hop into the solutions, let’s have a look at what is the global and local variables.

Local Variable Declarations vs. Global Variable Declarations

[Fixed] typeerror can’t compare datetime.datetime to datetime.date

Local Variable Referenced Before Assignment Error with Explanation

Try these examples yourself using our Online Compiler.

Let’s look at the following function:

Local Variable Referenced Before Assignment Error

Explanation

The variable myVar has been assigned a value twice. Once before the declaration of myFunction and within myFunction itself.

Using Global Variables

Passing the variable as global allows the function to recognize the variable outside the function.

Create Functions that Take in Parameters

Instead of initializing myVar as a global or local variable, it can be passed to the function as a parameter. This removes the need to create a variable in memory.

UnboundLocalError: local variable ‘DISTRO_NAME’

This error may occur when trying to launch the Anaconda Navigator in Linux Systems.

Upon launching Anaconda Navigator, the opening screen freezes and doesn’t proceed to load.

Try and update your Anaconda Navigator with the following command.

If solution one doesn’t work, you have to edit a file located at

After finding and opening the Python file, make the following changes:

In the function on line 159, simply add the line:

DISTRO_NAME = None

Save the file and re-launch Anaconda Navigator.

DJANGO – Local Variable Referenced Before Assignment [Form]

The program takes information from a form filled out by a user. Accordingly, an email is sent using the information.

Upon running you get the following error:

We have created a class myForm that creates instances of Django forms. It extracts the user’s name, email, and message to be sent.

A function GetContact is created to use the information from the Django form and produce an email. It takes one request parameter. Prior to sending the email, the function verifies the validity of the form. Upon True , .get() function is passed to fetch the name, email, and message. Finally, the email sent via the send_mail function

Why does the error occur?

We are initializing form under the if request.method == “POST” condition statement. Using the GET request, our variable form doesn’t get defined.

Local variable Referenced before assignment but it is global

This is a common error that happens when we don’t provide a value to a variable and reference it. This can happen with local variables. Global variables can’t be assigned.

This error message is raised when a variable is referenced before it has been assigned a value within the local scope of a function, even though it is a global variable.

Here’s an example to help illustrate the problem:

In this example, x is a global variable that is defined outside of the function my_func(). However, when we try to print the value of x inside the function, we get a UnboundLocalError with the message “local variable ‘x’ referenced before assignment”.

This is because the += operator implicitly creates a local variable within the function’s scope, which shadows the global variable of the same name. Since we’re trying to access the value of x before it’s been assigned a value within the local scope, the interpreter raises an error.

To fix this, you can use the global keyword to explicitly refer to the global variable within the function’s scope:

However, in the above example, the global keyword tells Python that we want to modify the value of the global variable x, rather than creating a new local variable. This allows us to access and modify the global variable within the function’s scope, without causing any errors.

Local variable ‘version’ referenced before assignment ubuntu-drivers

This error occurs with Ubuntu version drivers. To solve this error, you can re-specify the version information and give a split as 2 –

Here, p_name means package name.

With the help of the threading module, you can avoid using global variables in multi-threading. Make sure you lock and release your threads correctly to avoid the race condition.

When a variable that is created locally is called before assigning, it results in Unbound Local Error in Python. The interpreter can’t track the variable.

Therefore, we have examined the local variable referenced before the assignment Exception in Python. The differences between a local and global variable declaration have been explained, and multiple solutions regarding the issue have been provided.

Trending Python Articles

[Fixed] nameerror: name Unicode is not defined

Fixing Python UnboundLocalError: Local Variable ‘x’ Accessed Before Assignment

Understanding unboundlocalerror.

The UnboundLocalError in Python occurs when a function tries to access a local variable before it has been assigned a value. Variables in Python have scope that defines their level of visibility throughout the code: global scope, local scope, and nonlocal (in nested functions) scope. This error typically surfaces when using a variable that has not been initialized in the current function’s scope or when an attempt is made to modify a global variable without proper declaration.

Solutions for the Problem

To fix an UnboundLocalError, you need to identify the scope of the problematic variable and ensure it is correctly used within that scope.

Method 1: Initializing the Variable

Make sure to initialize the variable within the function before using it. This is often the simplest fix.

Method 2: Using Global Variables

If you intend to use a global variable and modify its value within a function, you must declare it as global before you use it.

Method 3: Using Nonlocal Variables

If the variable is defined in an outer function and you want to modify it within a nested function, use the nonlocal keyword.

That’s it. Happy coding!

Next Article: Fixing Python TypeError: Descriptor 'lower' for 'str' Objects Doesn't Apply to 'dict' Object

Previous Article: Python TypeError: write() argument must be str, not bytes

Series: Common Errors in Python and How to Fix Them

Related Articles

  • Python Warning: Secure coding is not enabled for restorable state
  • 4 ways to install Python modules on Windows without admin rights
  • Python TypeError: object of type ‘NoneType’ has no len()
  • Python: How to access command-line arguments (3 approaches)
  • Understanding ‘Never’ type in Python 3.11+ (5 examples)
  • Python: 3 Ways to Retrieve City/Country from IP Address
  • Using Type Aliases in Python: A Practical Guide (with Examples)
  • Python: Defining distinct types using NewType class
  • Using Optional Type in Python (explained with examples)
  • Python: How to Override Methods in Classes
  • Python: Define Generic Types for Lists of Nested Dictionaries
  • Python: Defining type for a list that can contain both numbers and strings

Search tutorials, examples, and resources

  • PHP programming
  • Symfony & Doctrine
  • Laravel & Eloquent
  • Tailwind CSS
  • Sequelize.js
  • Mongoose.js

unboundlocalerror local variable 'mid' referenced before assignment

Explore your training options in 10 minutes Get Started

  • Graduate Stories
  • Partner Spotlights
  • Bootcamp Prep
  • Bootcamp Admissions
  • University Bootcamps
  • Coding Tools
  • Software Engineering
  • Web Development
  • Data Science
  • Tech Guides
  • Tech Resources
  • Career Advice
  • Online Learning
  • Internships
  • Apprenticeships
  • Tech Salaries
  • Associate Degree
  • Bachelor's Degree
  • Master's Degree
  • University Admissions
  • Best Schools
  • Certifications
  • Bootcamp Financing
  • Higher Ed Financing
  • Scholarships
  • Financial Aid
  • Best Coding Bootcamps
  • Best Online Bootcamps
  • Best Web Design Bootcamps
  • Best Data Science Bootcamps
  • Best Technology Sales Bootcamps
  • Best Data Analytics Bootcamps
  • Best Cybersecurity Bootcamps
  • Best Digital Marketing Bootcamps
  • Los Angeles
  • San Francisco
  • Browse All Locations
  • Digital Marketing
  • Machine Learning
  • See All Subjects
  • Bootcamps 101
  • Full-Stack Development
  • Career Changes
  • View all Career Discussions
  • Mobile App Development
  • Cybersecurity
  • Product Management
  • UX/UI Design
  • What is a Coding Bootcamp?
  • Are Coding Bootcamps Worth It?
  • How to Choose a Coding Bootcamp
  • Best Online Coding Bootcamps and Courses
  • Best Free Bootcamps and Coding Training
  • Coding Bootcamp vs. Community College
  • Coding Bootcamp vs. Self-Learning
  • Bootcamps vs. Certifications: Compared
  • What Is a Coding Bootcamp Job Guarantee?
  • How to Pay for Coding Bootcamp
  • Ultimate Guide to Coding Bootcamp Loans
  • Best Coding Bootcamp Scholarships and Grants
  • Education Stipends for Coding Bootcamps
  • Get Your Coding Bootcamp Sponsored by Your Employer
  • GI Bill and Coding Bootcamps
  • Tech Intevriews
  • Our Enterprise Solution
  • Connect With Us
  • Publication
  • Reskill America
  • Partner With Us

Career Karma

  • Resource Center
  • Bachelor’s Degree
  • Master’s Degree

Python local variable referenced before assignment Solution

When you start introducing functions into your code, you’re bound to encounter an UnboundLocalError at some point. This error is raised when you try to use a variable before it has been assigned in the local context .

In this guide, we talk about what this error means and why it is raised. We walk through an example of this error in action to help you understand how you can solve it.

Find your bootcamp match

What is unboundlocalerror: local variable referenced before assignment.

Trying to assign a value to a variable that does not have local scope can result in this error:

Python has a simple rule to determine the scope of a variable. If a variable is assigned in a function , that variable is local. This is because it is assumed that when you define a variable inside a function you only need to access it inside that function.

There are two variable scopes in Python: local and global. Global variables are accessible throughout an entire program; local variables are only accessible within the function in which they are originally defined.

Let’s take a look at how to solve this error.

An Example Scenario

We’re going to write a program that calculates the grade a student has earned in class.

We start by declaring two variables:

These variables store the numerical and letter grades a student has earned, respectively. By default, the value of “letter” is “F”. Next, we write a function that calculates a student’s letter grade based on their numerical grade using an “if” statement :

Finally, we call our function:

This line of code prints out the value returned by the calculate_grade() function to the console. We pass through one parameter into our function: numerical. This is the numerical value of the grade a student has earned.

Let’s run our code and see what happens:

An error has been raised.

The Solution

Our code returns an error because we reference “letter” before we assign it.

We have set the value of “numerical” to 42. Our if statement does not set a value for any grade over 50. This means that when we call our calculate_grade() function, our return statement does not know the value to which we are referring.

We do define “letter” at the start of our program. However, we define it in the global context. Python treats “return letter” as trying to return a local variable called “letter”, not a global variable.

We solve this problem in two ways. First, we can add an else statement to our code. This ensures we declare “letter” before we try to return it:

Let’s try to run our code again:

Our code successfully prints out the student’s grade.

If you are using an “if” statement where you declare a variable, you should make sure there is an “else” statement in place. This will make sure that even if none of your if statements evaluate to True, you can still set a value for the variable with which you are going to work.

Alternatively, we could use the “global” keyword to make our global keyword available in the local context in our calculate_grade() function. However, this approach is likely to lead to more confusing code and other issues. In general, variables should not be declared using “global” unless absolutely necessary . Your first, and main, port of call should always be to make sure that a variable is correctly defined.

In the example above, for instance, we did not check that the variable “letter” was defined in all use cases.

That’s it! We have fixed the local variable error in our code.

The UnboundLocalError: local variable referenced before assignment error is raised when you try to assign a value to a local variable before it has been declared. You can solve this error by ensuring that a local variable is declared before you assign it a value.

Now you’re ready to solve UnboundLocalError Python errors like a professional developer !

About us: Career Karma is a platform designed to help job seekers find, research, and connect with job training programs to advance their careers. Learn about the CK publication .

What's Next?

icon_10

Get matched with top bootcamps

Ask a question to our community, take our careers quiz.

James Gallagher

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Apply to top tech training programs in one click

【Python】成功解决UnboundLocalError: local variable ‘a‘ referenced before assignment(几种场景下的解决方案)

unboundlocalerror local variable 'mid' referenced before assignment

【Python】成功解决UnboundLocalError: local variable ‘a’ referenced before assignment(几种场景下的解决方案)

🌈 欢迎莅临 我的 个人主页 👈这里是我 静心耕耘 深度学习领域、 真诚分享 知识与智慧的小天地!🎇 🎓 博主简介 : 985高校 的普通本硕,曾有幸发表过人工智能领域的 中科院顶刊一作论文,熟练掌握PyTorch框架 。 🔧 技术专长 : 在 CV 、 NLP 及 多模态 等领域有丰富的项目实战经验。已累计 一对一 为数百位用户提供 近千次 专业服务,助力他们 少走弯路、提高效率,近一年 好评率100% 。 📝 博客风采 : 积极分享关于 深度学习、PyTorch、Python 相关的实用内容。已发表原创文章 500余篇 ,代码分享次数 逾四万次 。 💡 服务项目 :包括但不限于 科研入门辅导 、 知识付费答疑 以及 个性化需求解决 。
欢迎添加👉👉👉 底部微信(gsxg605888) 👈👈👈与我交流           ( 请您备注来意 )           ( 请您备注来意 )           ( 请您备注来意 )

                             

🌵文章目录🌵

🐛一、什么是unboundlocalerror?, 🛠️二、如何解决unboundlocalerror?, 🌐三、实际场景中的解决方案, 📖四、深入理解作用域与变量生命周期, 🔍五、举一反三:其他常见错误与陷阱, 💡六、总结与最佳实践, 🎉结语.

                               

  在Python编程中, UnboundLocalError: local variable 'a' referenced before assignment 这个错误常常让初学者感到困惑。这个错误表明 你尝试在一个函数内部引用了一个局部变量,但是在引用之前并没有对它进行赋值 。换句话说, Python解释器在函数的作用域内找到了一个变量的引用,但是这个变量并没有在引用它之前被定义或赋值 。

下面是一个简单的例子,演示了如何触发这个错误:

在这个例子中,我们尝试在 a 被赋值之前就打印它的值,这会导致 UnboundLocalError 。

  要解决 UnboundLocalError ,你需要 确保在引用局部变量之前,该变量已经被正确地赋值 。这可以通过几种不同的方式实现。

确保在引用局部变量之前,该变量已经被正确赋值。

如果你打算在函数内部引用的是全局变量,那么需要使用 global 关键字来明确指定。

如果你希望变量有一个默认值,你可以使用函数的参数来提供这个默认值。

在某些情况下,你可能需要在使用变量之前检查它是否已经被定义。这可以通过使用 try-except 块来实现。

  在实际编程中, UnboundLocalError 可能会出现在更复杂的场景中。下面是一些实际案例及其解决方案。

场景1:在循环中引用和修改变量

在正确示例中,我们在循环中累加 i 到 total ,并在循环结束后打印 total 。注意,我们在累加之前已经对 total 进行了初始化,避免了 UnboundLocalError 。

场景2:在条件语句中引用变量

在正确示例中,我们在 if 语句中根据 x 的值计算 y ,然后在 if 语句外部打印 y 的值。我们使用了 if-else 语句确保了 y 在引用之前一定会被定义。

  在解决 UnboundLocalError 时,理解Python中的作用域和变量生命周期至关重要。作用域决定了变量的可见性,即变量在哪里可以被访问。而变量的生命周期则关系到变量的创建和销毁的时机。局部变量只在函数内部可见,并且当函数执行完毕后,它们的生命周期就结束了。全局变量在整个程序中都是可见的,它们的生命周期则与程序的生命周期一致。

  除了 UnboundLocalError 之外,Python编程中还有其他一些与变量作用域和生命周期相关的常见错误和陷阱。例如,不小心修改了全局变量而没有意识到,或者在循环中意外地创建了一个新的变量而不是更新现有的变量。避免这些错误的关键在于保持对变量作用域和生命周期的清晰理解,并谨慎地使用 global 关键字。

  解决 UnboundLocalError 的关键在于确保在引用局部变量之前已经对其进行了赋值。这可以通过在引用前赋值、使用全局变量、使用默认值或检查变量是否已定义等方式实现。同时,深入理解作用域和变量生命周期对于避免此类错误至关重要。最佳实践包括:

  • 在函数内部使用局部变量时,确保在引用之前已经对其进行了赋值。
  • 如果需要在函数内部修改全局变量,请使用 global 关键字明确声明。
  • 尽量避免在函数内部意外地创建新的全局变量。
  • 对于复杂的逻辑,使用明确的变量命名和注释来提高代码的可读性和可维护性。

通过遵循这些最佳实践,你可以减少 UnboundLocalError 的发生,并编写出更加健壮和可靠的Python代码。

  通过本文的学习,相信你已经对 UnboundLocalError 有了更深入的理解,并掌握了解决这一错误的几种方法。在实际编程中,遇到问题时不要害怕,要勇于探索和实践。通过不断学习和积累经验,你会逐渐成为一名优秀的Python程序员。加油!🚀

🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化 、 Python基础【高质量合集】 、 PyTorch零基础入门教程 👈 希望得到您的订阅和支持~ 💡 创作高质量博文(平均质量分92+),分享更多关于深度学习、PyTorch、Python领域的优质内容!(希望得到您的关注~)

unboundlocalerror local variable 'mid' referenced before assignment

“相关推荐”对你有帮助么?

unboundlocalerror local variable 'mid' referenced before assignment

请填写红包祝福语或标题

unboundlocalerror local variable 'mid' referenced before assignment

你的鼓励将是我创作的最大动力

unboundlocalerror local variable 'mid' referenced before assignment

您的余额不足,请更换扫码支付或 充值

unboundlocalerror local variable 'mid' referenced before assignment

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

unboundlocalerror local variable 'mid' referenced before assignment

UndboundLocalError: local variable referenced before assignment

Hello all, I’m using PsychoPy 2023.2.3 Win 10 x64bits

image

What I’m trying to do? The experiment will show in the middle of the screen an abstracted stimuli (B1 or B2), and after valid click on it, the stimulus will remain on the middle of the screen and three more stimuli will appear in the cornor of the screen.

I’m having this erro (attached above), a simple error, but I can not see where the error is. Also the experiment isn’t working proberly and is the old version (I don’t know but someone are having troubles with this version of PscyhoPy)? ba_training_block.xlsx (13.8 KB) SMTS.psyexp (91.6 KB) stimuli, instructions and parameters.xlsx (12.8 KB)

You have a routine called sample but you also use that name for your image file in sample_box .

I changed the name of the routine for ‘stimulus_sample’ and manteined the image file in sample_box as ‘sample’. But, the error still remain. But it do not happen all the time, this is very interesting…

Can u give it a look again? (I made some minor changes here)

image

Here the exp file ba_training_block.xlsx (13.7 KB) SMTS.psyexp (89.7 KB) stimuli, instructions and parameters.xlsx (12.8 KB)

Thanks again

Please could you confirm/show the new error message? Is it definitely still related to sample?

image

I think you have blank rows in your spreadsheet. The loop claims that there are 19 conditions but I think you only want 12. Without a value for sample_category sample doesn’t get set. With random presentation this will happen at a random point.

Related Topics

  • Python »
  • 3.14.0a0 Documentation »
  • Python 常見問題 »
  • Theme Auto Light Dark |

程式開發常見問答集 ¶

是否有可以使用在程式碼階段,具有中斷點,步驟執行等功能的除錯器? ¶.

下面描述了幾個 Python 除錯器,內建函式 breakpoint() 允許你進入其中任何一個。

pdb 模組是一個簡單但足夠的 Python 控制台模式除錯器。它是標準 Python 函式庫的一部分,並 記錄在函式庫參考手冊 中。你也可以參考 pdb 的程式碼作為範例來編寫自己的除錯器。

IDLE 交互式開發環境,它是標準 Python 發行版的一部分(通常作為 Tools/scripts/idle3 提供),包括一個圖形除錯器。

PythonWin 是一個 Python IDE,它包含一個基於 pdb 的 GUI 除錯器。 PythonWin 除錯器為斷點著色並具有許多很酷的功能,例如除錯非 PythonWin 程式。 PythonWin 作為 pywin32 專案的一部分和作為 ActivePython 的一部分發佈。

Eric 是一個基於 PyQt 和 Scintilla 編輯元件所建構的 IDE。

trepan3k 是一個類似 gdb 的除錯器。

Visual Studio Code 是一個整合了版本控制軟體與除錯工具的 IDE。

有數個商業化Python整合化開發工具包含圖形除錯功能。這些包含:

有沒有工具能夠幫忙找 bug 或執行靜態分析? ¶

Pylint 和 Pyflakes 進行基本檢查以幫助你儘早抓出錯誤。

靜態型別檢查器,例如 Mypy 、 Pyre 和 Pytype 可以檢查 Python 原始碼中的型別提示。

如何從 Python 腳本建立獨立的二進位檔案? ¶

如果只是想要一个独立的程序,以便用户不必预先安装 Python 即可下载和运行它,则不需要将 Python 编译成 C 代码。有许多工具可以检测程序所需的模块,并将这些模块与 Python 二进制程序捆绑在一起生成单个可执行文件。

一种方案是使用 freeze 工具,它以 Tools/freeze 的形式包含在 Python 源代码树中。 它可将 Python 字节码转换为 C 数组;你可以使用 C 编译器将你的所有模块嵌入到一个新程序中,再将其与标准 Python 模块进行链接。

它的工作原理是递归扫描源代码,获取两种格式的 import 语句,并在标准 Python 路径和源码目录(用于内置模块)检索这些模块。然后,把这些模块的 Python 字节码转换为 C 代码(可以利用 marshal 模块转换为代码对象的数组初始化器),并创建一个定制的配置文件,该文件仅包含程序实际用到的内置模块。然后,编译生成的 C 代码并将其与 Python 解释器的其余部分链接,形成一个自给自足的二进制文件,其功能与 Python 脚本代码完全相同。

以下套件可以幫助建立 console 和 GUI 可執行檔案:

Nuitka (跨平台)

PyInstaller (跨平台)

PyOxidizer (跨平台)

cx_Freeze (跨平台)

py2app (僅限 macOS)

py2exe (僅限 Windows)

Python 程式碼是否有編碼標準或風格指南? ¶

是的。標準函式庫模組所需的編碼風格稱為 PEP 8 。

為什麼當變數有值時,我仍得到錯誤訊息 UnboundLocalError? ¶

当在函数内部某处添加了一条赋值语句,因而导致之前正常工作的代码报出 UnboundLocalError 错误,这确实有点令人惊讶。

可以執行,但是這段程式:

導致 UnboundLocalError :

原因就是,当对某作用域内的变量进行赋值时,该变量将成为该作用域内的局部变量,并覆盖外部作用域中的同名变量。由于 foo 的最后一条语句为 x 分配了一个新值,编译器会将其识别为局部变量。因此,前面的 print(x) 试图输出未初始化的局部变量,就会引发错误。

在上面的示例中,你可以透過將其聲明為全域變數來存取外部範圍變數:

与类和实例变量貌似但不一样,其实以上是在修改外部作用域的变量值,为了提示这一点,这里需要显式声明一下。

你可以使用 nonlocal 关键字在嵌套作用域中执行类似的操作:

Python 的區域變數和全域變數有什麼規則? ¶

函数内部只作引用的 Python 变量隐式视为全局变量。如果在函数内部任何位置为变量赋值,则除非明确声明为全局变量,否则均将其视为局部变量。

起初尽管有点令人惊讶,不过考虑片刻即可释然。一方面,已分配的变量要求加上 global 可以防止意外的副作用发生。另一方面,如果所有全局引用都要加上 global ,那处处都得用上 global 了。那么每次对内置函数或导入模块中的组件进行引用时,都得声明为全局变量。这种杂乱会破坏 global 声明用于警示副作用的有效性。

为什么在循环中定义的参数各异的 lambda 都返回相同的结果? ¶

假設你使用 for 循環來定義幾個不同的 lambda(甚至是普通函式),例如:

以上会得到一个包含5个 lambda 函数的列表,这些函数将计算 x**2 。大家或许期望,调用这些函数会分别返回 0 、 1 、 4 、 9 和 16 。然而,真的试过就会发现,他们都会返回 16 :

这是因为 x 不是 lambda 函数的内部变量,而是定义于外部作用域中的,并且 x 是在调用 lambda 时访问的——而不是在定义时访问。循环结束时 x 的值是 4 ,所以此时所有的函数都将返回 4**2 ,即 16 。通过改变 x 的值并查看 lambda 的结果变化,也可以验证这一点。

为了避免发生上述情况,需要将值保存在 lambda 局部变量,以使其不依赖于全局 x 的值:

以上 n=x 创建了一个新的 lambda 本地变量 n ,并在定义 lambda 时计算其值,使其与循环当前时点的 x 值相同。这意味着 n 的值在第 1 个 lambda 中为 0 ,在第 2 个 lambda 中为 1 ,在第 3 个中为 2 ,依此类推。因此现在每个 lambda 都会返回正确结果:

請注意,此行為並非 lambda 所特有,也適用於常規函式。

如何跨模組共享全域變數? ¶

在单个程序中跨模块共享信息的规范方法是创建一个特殊模块(通常称为 config 或 cfg)。只需在应用程序的所有模块中导入该 config 模块;然后该模块就可当作全局名称使用了。因为每个模块只有一个实例,所以对该模块对象所做的任何更改将会在所有地方得以体现。 例如:

请注意,出于同样的原因,使用模块也是实现单例设计模式的基础。

导入模块的“最佳实践”是什么? ¶

通常请勿使用 from modulename import * 。因为这会扰乱 importer 的命名空间,且会造成未定义名称更难以被 Linter 检查出来。

请在代码文件的首部就导入模块。这样代码所需的模块就一目了然了,也不用考虑模块名是否在作用域内的问题。每行导入一个模块则增删起来会比较容易,每行导入多个模块则更节省屏幕空间。

按如下顺序导入模块就是一种好做法:

标准库模块——例如: sys 、 os 、 argparse 、 re 等。

第三方库模块(安装于 Python site-packages 目录中的内容)——例如: dateutil 、 requests 、 PIL.Image 等。

为了避免循环导入引发的问题,有时需要将模块导入语句移入函数或类的内部。Gordon McMillan 的说法如下:

当两个模块都采用 "import <module>" 的导入形式时,循环导入是没有问题的。但如果第 2 个模块想从第 1 个模块中取出一个名称("from module import name")并且导入处于代码的最顶层,那导入就会失败。原因是第 1 个模块中的名称还不可用,这时第 1 个模块正忙于导入第 2 个模块呢。

如果只是在一个函数中用到第 2 个模块,那这时将导入语句移入该函数内部即可。当调用到导入语句时,第 1 个模块将已经完成初始化,第 2 个模块就可以进行导入了。

如果某些模块是平台相关的,可能还需要把导入语句移出最顶级代码。这种情况下,甚至有可能无法导入文件首部的所有模块。于是在对应的平台相关代码中导入正确的模块,就是一种不错的选择。

只有为了避免循环导入问题,或有必要减少模块初始化时间时,才把导入语句移入类似函数定义内部的局部作用域。如果根据程序的执行方式,许多导入操作不是必需的,那么这种技术尤其有用。如果模块仅在某个函数中用到,可能还要将导入操作移入该函数内部。请注意,因为模块有一次初始化过程,所以第一次加载模块的代价可能会比较高,但多次加载几乎没有什么花费,代价只是进行几次字典检索而已。即使模块名超出了作用域,模块在 sys.modules 中也是可用的。

为什么对象之间会共享默认值? ¶

新手程序员常常中招这类 Bug。请看以下函数:

第一次调用此函数时, mydict 中只有一个数据项。第二次调用 mydict 则会包含两个数据项,因为 foo() 开始执行时, mydict 中已经带有一个数据项了。

大家往往希望,函数调用会为默认值创建新的对象。但事实并非如此。默认值只会在函数定义时创建一次。如果对象发生改变,就如上例中的字典那样,则后续调用该函数时将会引用这个改动的对象。

按照定义,不可变对象改动起来是安全的,诸如数字、字符串、元组和 None 之类。而可变对象的改动则可能引起困惑,例如字典、列表和类实例等。

因此,不把可变对象用作默认值是一种良好的编程做法。而应采用 None 作为默认值,然后在函数中检查参数是否为 None 并新建列表、字典或其他对象。例如,代码不应如下所示:

参数默认值的特性有时会很有用处。 如果有个函数的计算过程会比较耗时,有一种常见技巧是将每次函数调用的参数和结果缓存起来,并在同样的值被再次请求时返回缓存的值。这种技巧被称为“memoize”,实现代码可如下所示:

也可以不用参数默认值来实现,而是采用全局的字典变量;这取决于个人偏好。

如何将可选参数或关键字参数从一个函数传递到另一个函数? ¶

请利用函数参数列表中的标识符 * 和 ** 归集实参;结果会是元组形式的位置实参和字典形式的关键字实参。然后就可利用 * 和 ** 在调用其他函数时传入这些实参:

引數 (arguments) 和參數 (parameters) 有什麼區別? ¶

形参 是由出现在函数定义中的名称来定义的,而 参数 则是在调用函数时实际传入的值。 形参定义了一个函数能接受什么 参数种类 。 例如,对于以下函数定义:

foo 、 bar 和 kwargs 是 func 的參數。然而,當呼叫 func 時,例如:

42 、 314 和 somevar 是引數。

為什麼更改 list 'y' 也會更改 list 'x'? ¶

如果你寫了像這樣的程式碼:

你可能想知道為什麼將一個元素附加到 y 時也會改變 x 。

產生這個結果的原因有兩個:

变量只是指向对象的一个名称。执行 y = x 并不会创建列表的副本——而只是创建了一个新变量 y ,并指向 x 所指的同一对象。这就意味着只存在一个列表对象, x 和 y 都是对它的引用。

list 是 mutable ,這意味著你可以變更它們的內容。

在调用 append() 之后,该可变对象的内容由 [] 变为 [10] 。 由于两个变量引用了同一对象,因此用其中任意一个名称所访问到的都是修改后的值 [10] 。

如果把赋给 x 的对象换成一个不可变对象:

可见这时 x 和 y 就不再相等了。因为整数是 immutable 对象,在执行 x = x + 1 时,并不会修改整数对象 5 ,给它加上 1;而是创建了一个新的对象(整数对象 6 )并将其赋给 x (也就是改变了 x 所指向的对象)。在赋值完成后,就有了两个对象(整数对象 6 和 5 )和分别指向他俩的两个变量( x 现在指向 6 而 y 仍然指向 5 )。

某些操作 (例如 y.append(10) 和 y.sort() ) 是改变原对象,而看上去相似的另一些操作 (例如 y = y + [10] 和 sorted(y) <sorted>) 则是创建新对象。 通常在 Python 中 (以及在标准库的所有代码中) 会改变原对象的方法将返回 ``None`() 以帮助避免混淆这两种不同类型的操作。 因此如果你错误地使用了 y.sort() 并期望它将返回一个经过排序的 y 的副本,你得到的结果将会是 None ,这将导致你的程序产生一个容易诊断的错误。

不过还存在一类操作,用不同的类型执行相同的操作有时会发生不同的行为:即增量赋值运算符。例如, += 会修改列表,但不会修改元组或整数( a_list += [1, 2, 3] 与 a_list.extend([1, 2, 3]) 同样都会改变 a_list ,而 some_tuple += (1, 2, 3) 和 some_int += 1 则会创建新的对象)。

对于一个可变对象( list 、 dict 、 set 等等),可以利用某些特定的操作进行修改,所有引用它的变量都会反映出改动情况。

对于一个不可变对象( str 、 int 、 tuple 等),所有引用它的变量都会给出相同的值,但所有改变其值的操作都将返回一个新的对象。

如要知道两个变量是否指向同一个对象,可以利用 is 运算符或内置函数 id() 。

如何编写带有输出参数的函数(按照引用调用)? ¶

请记住,Python 中的实参是通过赋值传递的。由于赋值只是创建了对象的引用,所以调用方和被调用方的参数名都不存在别名,本质上也就不存在按引用调用的方式。通过以下几种方式,可以得到所需的效果。

这差不多是最明晰的解决方案了。

使用全局变量。这不是线程安全的方案,不推荐使用。

传递一个可变(即可原地修改的) 对象:

传入一个接收可变对象的字典:

或者把值用类实例封装起来:

没有什么理由要把问题搞得这么复杂。

最佳选择就是返回一个包含多个结果值的元组。

如何在 Python 中创建高阶函数? ¶

有两种选择:嵌套作用域、可调用对象。假定需要定义 linear(a,b) ,其返回结果是一个计算出 a*x+b 的函数 f(x) 。 采用嵌套作用域的方案如下:

都会得到一个可调用对象,可实现 taxes(10e6) == 0.3 * 10e6 + 2 。

可调用对象的方案有个缺点,就是速度稍慢且生成的代码略长。不过值得注意的是,同一组可调用对象能够通过继承来共享签名(类声明):

物件可以封裝多個方法的狀態:

這裡的 inc() 、 dec() 和 reset() 就像共享相同計數變數的函式一樣。

如何在 Python 中複製物件? ¶

一般情况下,用 copy.copy() 或 copy.deepcopy() 基本就可以了。并不是所有对象都支持复制,但多数是可以的。

某些对象可以用更简便的方法进行复制。比如字典对象就提供了 copy() 方法:

序列可以透過切片 (slicing) 複製:

如何找到物件的方法或屬性? ¶

对于一个用户定义类的实例 x , dir(x) 将返回一个按字母顺序排列的名称列表,其中包含实例属性及由类定义的方法和属性。

我的程式碼如何發現物件的名稱? ¶

一般而言这是无法实现的,因为对象并不存在真正的名称。赋值本质上是把某个名称绑定到某个值上; def 和 class 语句同样如此,只是值换成了某个可调用对象。比如以下代码:

可以不太严谨地说上述类有一个名称:即使它绑定了两个名称并通过名称 B 发起调用所创建的实例仍将被报告为类 A 的实例。 但是,没有办法肯定地说实例的名称是 a 还是 b ,因为这两个名称都被绑定到同一个值上了。

代码一般没有必要去“知晓”某个值的名称。通常这种需求预示着还是改变方案为好,除非真的是要编写内审程序。

在 comp.lang.python 中,Fredrik Lundh 曾針對這個問題給出了一個極好的比喻:

就像你在門廊上發現的那隻貓的名字一樣:貓(物件)本身不能告訴你它的名字,它也不關心 - 所以找出它叫什麼的唯一方法是詢問所有鄰居(命名空間)是否是他們的貓(物件)... ....如果你發現它有很多名字,或者根本沒有名字,請不要感到驚訝!

逗号运算符的优先级是什么? ¶

逗号不是 Python 的运算符。 请看以下例子:

由于逗号不是运算符,而只是表达式之间的分隔符,因此上述代码就相当于:

对于各种赋值运算符( = 、 += 等)来说同样如此。他们并不是真正的运算符,而只是赋值语句中的语法分隔符。

是否有等效於 C 的 "?:" 三元運算子? ¶

在 Python 2.5 引入上述语法之前,通常的做法是使用逻辑运算符:

然而这种做法并不保险,因为当 on_true 为布尔值“假”时,结果将会出错。所以肯定还是采用 ... if ... else ... 形式为妙。

是否可以用 Python 编写让人眼晕的单行程序? ¶

可以。 这一般是通过在 lambda 中嵌套 lambda 来实现的。 请参阅以下三个示例,它们是基于 Ulf Bartelt 的代码改写的:

孩子們,不要在家裡嘗試這個!

函数形参列表中的斜杠(/)是什么意思? ¶

函数参数列表中的斜杠表示在它之前的形参都是仅限位置形参。 仅限位置形参没有可供外部使用的名称。 在调用接受仅限位置形参的函数时,参数将只根据其位置被映射到形参上。 例如, divmod() 就是一个接受仅限位置形参的函数。 它的文档说明是这样的:

形参列表尾部的斜杠说明,两个形参都是仅限位置形参。因此,用关键字参数调用 divmod() 将会引发错误:

如何指定十六進位和八進位整數? ¶

要给出八进制数,需在八进制数值前面加上一个零和一个小写或大写字母 "o" 作为前缀。例如,要将变量 "a" 设为八进制的 "10" (十进制的 8),写法如下:

十六进制数也很简单。只要在十六进制数前面加上一个零和一个小写或大写的字母 "x"。十六进制数中的字母可以为大写或小写。比如在 Python 解释器中输入:

為什麼 -22 // 10 回傳 -3? ¶

这主要是为了让 i % j 的正负与 j 一致,如果期望如此,且期望如下等式成立:

那麼整數除法必須回傳向下取整的結果。 C 還要求保留​​該識別性,然後截斷 i // j 的編譯器需要使 i % j 具有與 i 相同的符號。

对于 i % j 来说 j 为负值的应用场景实际上是非常少的。 而 j 为正值的情况则非常多,并且实际上在所有情况下让 i % j 的结果为 >= 0 会更有用处。 如果现在时间为 10 时,那么 200 小时前应是几时? -190 % 12 == 2 是有用处的; -190 % 12 == -10 则是会导致意外的漏洞。

我如何获得 int 字面属性而不是 SyntaxError ? ¶

尝试以正式方式查找一个 int 字面值属性会发生 SyntaxError 因为句点会被当作是小数点:

解决办法是用空格或括号将字词与句号分开。

如何將字串轉換為數字? ¶

对于整数,可使用内置的 int() 类型构造器,例如 int('144') == 144 。 类似地,可使用 float() 转换为浮点数,例如 float('144') == 144.0 。

默认情况下,这些操作会将数字按十进制来解读,因此 int('0144') == 144 为真值,而 int('0x144') 会引发 ValueError 。 int(string, base) 接受第二个可选参数指定转换的基数,例如 int( '0x144', 16) == 324 。 如果指定基数为 0,则按 Python 规则解读数字:前缀 '0o' 表示八进制,而 '0x' 表示十六进制。

如果只是想把字符串转为数字,请不要使用内置函数 eval() 。 eval() 的速度慢很多且存在安全风险:别人可能会传入带有不良副作用的 Python 表达式。比如可能会传入 __import__('os').system("rm -rf $HOME") ,这会把 home 目录给删了。

eval() 还有把数字解析为 Python 表达式的后果,因此如 eval('09') 将会导致语法错误,因为 Python 不允许十进制数带有前导 '0'('0' 除外)。

如何將數字轉換為字串? ¶

例如,要把数字 144 转换为字符串 '144' ,可使用内置类型构造器 str() 。 如果你需要十六进制或八进制表示形式,可使用内置函数 hex() 或 oct() 。 更复杂的格式化方式,请参阅 f-string(f 字串) 和 格式化文字語法 等章节,例如 "{:04d}".format(144) 将产生 '0144' 而 "{:.3f}".format(1.0/3.0) 将产生 '0.333' 。

无法修改,因为字符串是不可变对象。 在大多数情况下,只要将各个部分组合起来构造出一个新字符串即可。如果需要一个能原地修改 Unicode 数据的对象,可以试试 io.StringIO 对象或 array 模块:

如何使用字符串调用函数/方法? ¶

最好的做法是采用一个字典,将字符串映射为函数。其主要优势就是字符串不必与函数名一样。这也是用来模拟 case 结构的主要技巧:

利用内置函数 getattr() :

请注意 getattr() 可用于任何对象,包括类、类实例、模块等等。

标准库就多次使用了这个技巧,例如:

用 locals() 解析出函数名:

是否有与Perl 的chomp() 等效的方法,用于从字符串中删除尾随换行符? ¶

可以使用 S.rstrip("\r\n") 从字符串 S 的末尾删除所有的换行符,而不删除其他尾随空格。如果字符串 S 表示多行,且末尾有几个空行,则将删除所有空行的换行符:

由于通常只在一次读取一行文本时才需要这样做,所以使用 S.rstrip() 这种方式工作得很好。

是否有 scanf() 或 sscanf() 的等价函数? ¶

对于简单的输入解析,最容易的做法通常是用字符串对象的 split() 方法将一行内容按空白分隔符拆分为多个单词再用 int() 或 float() 将十进制数值字符串转换为数值。 split() 支持可选的 "sep" 形参,适用于分隔符不是空白符的情况。

对于更复杂的输入解析,正则表达式相比 C 的 sscanf 更为强大也更为适合。

'UnicodeDecodeError' 或 'UnicodeEncodeErro' 錯誤是什麼意思? ¶

請參閱 Unicode 指南 。

我能以奇数个反斜杠来结束一个原始字符串吗? ¶

以奇数个反斜杠结尾的原始字符串将会转义用于标记字符串的引号:

有几种绕过此问题的办法。 其中之一是使用常规字符串以及双反斜杠:

另一种办法是将一个包含被转义反斜杠的常规字符串拼接到原始字符串上:

在 Windows 上还可以使用 os.path.join() 来添加反斜杠:

请注意虽然在确定原始字符串的结束位置时反斜杠会对引号进行“转义“,但在解析原始字符串的值时并不会发生转义。 也就是说,反斜杠会被保留在原始字符串的值中:

另请参阅 语言参考 中的规范说明。

我的程序太慢了。该如何加快速度? ¶

总的来说,这是个棘手的问题。在进一步讨论之前,首先应该记住以下几件事:

不同的 Python 实现具有不同的性能特点。 本 FAQ 着重解答的是 CPython 。

不同操作系统可能会有不同表现,尤其是涉及 I/O 和多线程时。

在尝试优化代码 之前 ,务必要先找出程序中的热点(请参阅 profile 模块)。

编写基准测试脚本,在寻求性能提升的过程中就能实现快速迭代(请参阅 timeit 模块)。

强烈建议首先要保证足够高的代码测试覆盖率(通过单元测试或其他技术),因为复杂的优化有可能会导致代码回退。

话虽如此,Python 代码的提速还是有很多技巧的。以下列出了一些普适性的原则,对于让性能达到可接受的水平会有很大帮助:

相较于试图对全部代码铺开做微观优化,优化算法(或换用更快的算法)可以产出更大的收益。

使用正确的数据结构。参考 內建型別 和 collections 模块的文档。

如果标准库已为某些操作提供了基础函数,则可能(当然不能保证)比所有自编的函数都要快。对于用 C 语言编写的基础函数则更是如此,比如内置函数和一些扩展类型。例如,一定要用内置方法 list.sort() 或 sorted() 函数进行排序(某些高级用法的示例请参阅 排序技法 )。

抽象往往会造成中间层,并会迫使解释器执行更多的操作。如果抽象出来的中间层级太多,工作量超过了要完成的有效任务,那么程序就会被拖慢。应该避免过度的抽象,而且往往也会对可读性产生不利影响,特别是当函数或方法比较小的时候。

如果你已经达到纯 Python 允许的限制,那么有一些工具可以让你走得更远。 例如, Cython 可以将稍加修改的 Python 代码版本编译为 C 扩展,并能在许多不同的平台上使用。 Cython 可以利用编译(和可选的类型标注)来让你的代码显著快于解释运行时的速度。 如果你对自己的 C 编程技能有信心,还可以自行 编写 C 扩展模块 。

有個 wiki 頁面專門介紹 效能改進小提示 。

将多个字符串连接在一起的最有效方法是什么? ¶

str 和 bytes 对象是不可变的,因此连接多个字符串的效率会很低,因为每次连接都会创建一个新的对象。一般情况下,总耗时与字符串总长是二次方的关系。

如果要连接多个 str 对象,通常推荐的方案是先全部放入列表,最后再调用 str.join() :

(还有一种合理高效的习惯做法,就是利用 io.StringIO )

如果要连接多个 bytes 对象,推荐做法是用 bytearray 对象的原地连接操作( += 运算符)追加数据:

序列(元组/列表) ¶

如何在元组和列表之间进行转换? ¶.

类型构造器 tuple(seq) 可将任意序列(实际上是任意可迭代对象)转换为数据项和顺序均不变的元组。

例如, tuple([1, 2, 3]) 会生成 (1, 2, 3) , tuple('abc') 则会生成 ('a', 'b', 'c') 。 如果参数就是元组,则不会创建副本而是返回同一对象,因此如果无法确定某个对象是否为元组时,直接调用 tuple() 也没什么代价。

类型构造器 list(seq) 可将任意序列或可迭代对象转换为数据项和顺序均不变的列表。例如, list((1, 2, 3)) 会生成 [1, 2, 3] 而 list('abc') 则会生成 ['a', 'b', 'c'] 。如果参数即为列表,则会像 seq[:] 那样创建一个副本。

Python 序列的索引可以是正数或负数。索引为正数时,0 是第一个索引值, 1 为第二个,依此类推。索引为负数时,-1 为倒数第一个索引值,-2 为倒数第二个,依此类推。可以认为 seq[-n] 就相当于 seq[len(seq)-n] 。

使用负数序号有时会很方便。 例如 S[:-1] 就是原字符串去掉最后一个字符,这可以用来移除某个字符串末尾的换行符。

序列如何以逆序遍历? ¶

使用内置函数 reversed() :

原序列不会变化,而是构建一个逆序的新副本以供遍历。

如何从列表中删除重复项? ¶

许多完成此操作的的详细介绍,可参阅 Python Cookbook:

https://code.activestate.com/recipes/52560/

如果列表允许重新排序,不妨先对其排序,然后从列表末尾开始扫描,依次删除重复项:

如果列表的所有元素都能用作集合的键(即都是 hashable ),以下做法速度往往更快:

以上操作会将列表转换为集合,从而删除重复项,然后返回成列表。

如何从列表中删除多个项? ¶

类似于删除重复项,一种做法是反向遍历并根据条件删除。不过更简单快速的做法就是切片替换操作,采用隐式或显式的正向迭代遍历。以下是三种变体写法:

列表推导式可能是最快的。

如何在 Python 中创建数组? ¶

列表在时间复杂度方面相当于 C 或 Pascal 的数组;主要区别在于,Python 列表可以包含多种不同类型的对象。

array 模块也提供了一些创建具有紧凑表示形式的固定类型数据的方法,但其索引速度要比列表慢。 还可关注 NumPy 和其他一些第三方包也定义了一些各具特色的数组类结构体。

要获得 Lisp 风格的列表,可以使用元组来模拟 cons 单元 :

如果需要可变特性,你可以用列表来代替元组。 在这里模拟 Lisp car 的是 lisp_list[0] 而模拟 cdr 的是 lisp_list[1] 。 只有在你确定真有需要时才这样做,因为这通常会比使用 Python 列表要慢上许多。

如何创建多维列表? ¶

多维数组或许会用以下方式建立:

但如果给某一项赋值,结果会同时在多个位置体现出来:

原因在于用 * 对列表执行重复操作并不会创建副本,而只是创建现有对象的引用。 *3 创建的是包含 3 个引用的列表,每个引用指向的是同一个长度为 2 的列表。1 处改动会体现在所有地方,这一定不是应有的方案。

推荐做法是先创建一个所需长度的列表,然后将每个元素都填充为一个新建列表。

以上生成了一个包含 3 个列表的列表,每个子列表的长度为 2。也可以采用列表推导式:

或者,你也可以使用提供矩阵数据类型的扩展;其中最著名的是 NumPy 。

我如何将一个方法或函数应用于由对象组成的序列? ¶

要调用一个方法或函数并将返回值累积到一个列表中, list comprehension 是一种优雅的解决方案:

如果只需运行方法或函数而不保存返回值,那么一个简单的 for 循环就足够了:

为什么 a_tuple[i] += ['item'] 会引发异常? ¶

这是由两个因素共同导致的,一是增强赋值运算符属于 赋值 运算符,二是 Python 可变和不可变对象之间的差别。

只要元组的元素指向可变对象,这时对元素进行增强赋值,那么这里介绍的内容都是适用的。在此只以 list 和 += 举例。

触发异常的原因显而易见: 1 会与指向( 1 )的对象 a_tuple[0] 相加,生成结果对象 2 ,但在试图将运算结果 2 赋值给元组的 0 号元素时就会报错,因为元组元素的指向无法更改。

其实在幕后,上述增强赋值语句的执行过程大致如下:

由于元组是不可变的,因此赋值这步会引发错误。

这时触发异常会令人略感惊讶,更让人吃惊的是虽有报错,但加法操作却生效了:

要明白为什么会这样,你需要知道 (a) 如果一个对象实现了 __iadd__() 魔术方法,那么它就会在执行 += 增强赋值时被调用,并且其返回值将在赋值语句中被使用;(b) 对于列表而言, __iadd__() 等价于在列表上调用 extend() 并返回该列表。 所以对于列表我们可以这样说, += 就是 list.extend() 的“快捷方式”:

a_list 所引用的对象已被修改,而引用被修改对象的指针又重新被赋值给 a_list 。 赋值的最终结果没有变化,因为它是引用 a_list 之前所引用的同一对象的指针,但仍然发生了赋值操作。

因此,在此元组示例中,发生的事情等同于:

__iadd__() 执行成功,因此列表得到了扩充,但是即使 result 是指向 a_tuple[0] 所指向的同一个对象,最后的赋值仍然会导致错误,因为元组是不可变的。

我想做一个复杂的排序:能用 Python 进行施瓦茨变换吗? ¶

归功于 Perl 社区的 Randal Schwartz,该技术根据度量值对列表进行排序,该度量值将每个元素映射为“顺序值”。在 Python 中,请利用 list.sort() 方法的 key 参数:

如何根据另一个列表的值对某列表进行排序? ¶

将它们合并到元组的迭代器中,对结果列表进行排序,然后选择所需的元素。

什麼是類別 (class)? ¶

类是通过执行 class 语句创建的某种对象的类型。创建实例对象时,用 Class 对象作为模板,实例对象既包含了数据(属性),又包含了数据类型特有的代码(方法)。

类可以基于一个或多个其他类(称之为基类)进行创建。基类的属性和方法都得以继承。这样对象模型就可以通过继承不断地进行细化。比如通用的 Mailbox 类提供了邮箱的基本访问方法.,它的子类 MboxMailbox 、 MaildirMailbox 、 OutlookMailbox 则能够处理各种特定的邮箱格式。

什麼是方法 (method)? ¶

方法是属于对象的函数,对于对象 x ,通常以 x.name(arguments...) 的形式调用。方法以函数的形式给出定义,位于类的定义内:

什么是 self ? ¶

Self 只是方法的第一个参数的习惯性名称。假定某个类中有个方法定义为 meth(self, a, b, c) ,则其实例 x 应以 x.meth(a, b, c) 的形式进行调用;而被调用的方法则应视其为做了 meth(x, a, b, c) 形式的调用。

另請參閱 為何「self」在方法 (method) 定義和呼叫時一定要明確使用? 。

如何检查对象是否为给定类或其子类的一个实例? ¶

使用内置函数 isinstance(obj, cls) 。 你可以检测对象是否属于多个类中的某一个的实例,只要提供一个元组而非单个类即可,如 isinstance(obj, (class1, class2, ...)) ,还可以检测对象是否属于 Python 的某个内置类型,如 isinstance(obj, str) 或 isinstance(obj, (int, float, complex)) 。

请注意 isinstance() 还会检测派生自 abstract base class 的虚继承。 因此对于已注册的类,即便没有直接或间接继承自抽象基类,对抽象基类的检测都将返回 True 。要想检测“真正的继承”,请扫描类的 MRO :

请注意,大多数程序不会经常用 isinstance() 对用户自定义类进行检测。 如果是自已开发的类,更合适的面向对象编程风格应该是在类中定义多种方法,以封装特定的行为,而不是检查对象属于什么类再据此干不同的事。假定有如下执行某些操作的函数:

更好的方法是在所有类上定义一个 search() 方法,然后调用它:

委托是一种面向对象的技术(也称为设计模式)。假设对象 x 已经存在,现在想要改变其某个方法的行为。可以创建一个新类,其中提供了所需修改方法的新实现,而将所有其他方法都委托给 x 的对应方法。

Python 程序员可以轻松实现委托。比如以下实现了一个类似于文件的类,只是会把所有写入的数据转换为大写:

这里 UpperOut 类重新定义了 write() 方法,在调用下层的 self._outfile.write() 方法之前将参数字符串转换为大写形式。 所有其他方法都被委托给下层的 self._outfile 对象。 委托是通过 __getattr__() 方法完成的;请参阅 语言参考 了解有关控制属性访问的更多信息。

请注意在更一般的情况下委托可能会变得比较棘手。 当属性即需要被设置又需要被提取时,类还必须定义 __setattr__() 方法,而这样做必须十分小心。 __setattr__() 的基本实现大致如下所示:

大多数 __setattr__() 实现都必须修改 self.__dict__ 来为自身保存局部状态而不至于造成无限递归。

如何在扩展基类的派生类中调用基类中定义的方法? ¶

使用内置的 super() 函数:

在下面的例子中, super() 将自动根据它的调用方 ( self 值) 来确定实例对象,使用 type(self).__mro__ 查找 method resolution order (MRO),并返回 MRO 中位于 Derived 之后的项: Base 。

如何让代码更容易对基类进行修改? ¶

可以为基类赋一个别名并基于该别名进行派生。这样只要修改赋给该别名的值即可。顺便提一下,如要动态地确定(例如根据可用的资源)该使用哪个基类,这个技巧也非常方便。例如:

如何创建静态类数据和静态类方法? ¶

Python 支持静态数据和静态方法(以 C++ 或 Java 的定义而言)。

静态数据只需定义一个类属性即可。若要为属性赋新值,则必须在赋值时显式使用类名:

对于所有符合 isinstance(c, C) 的 c , c.count 也同样指向 C.count ,除非被 c 自身或者被从 c.__class__ 回溯到基类 C 的搜索路径上的某个类所覆盖。

注意:在 C 的某个方法内部,像 self.count = 42 这样的赋值将在 self 自身的字典中新建一个名为 "count" 的不相关实例。 想要重新绑定类静态数据名称就必须总是指明类名,无论是在方法内部还是外部:

Python 支持静态方法:

不过为了获得静态方法的效果,还有一种做法直接得多,也即使用模块级函数即可:

如果代码的结构化比较充分,每个模块只定义了一个类(或者多个类的层次关系密切相关),那就具备了应有的封装。

在 Python 中如何重载构造函数(或方法)? ¶

这个答案实际上适用于所有方法,但问题通常首先出现于构造函数的应用场景中。

在 C++ 中,代码会如下所示:

在 Python 中,只能编写一个构造函数,并用默认参数捕获所有情况。例如:

这不完全等同,但在实践中足够接近。

也可以试试采用变长参数列表,例如:

上述做法同样适用于所有方法定义。

在用 __spam 的时候得到一个类似 _SomeClassName__spam 的错误信息。 ¶

以双下划线打头的变量名会被“破坏”,以便以一种简单高效的方式定义类私有变量。任何形式为 __spam 的标识符(至少前缀两个下划线,至多后缀一个下划线)文本均会被替换为 _classname__spam ,其中 classname 为去除了全部前缀下划线的当前类名称。

这并不能保证私密性:外部用户仍然可以访问 "_classname__spam" 属性,私有变量值也在对象的 __dict__ 中可见。 许多 Python 程序员根本不操心要去使用私有变量名。

类定义了 __del__ 方法,但是删除对象时没有调用它。 ¶

del 语句不一定要调用 __del__() -- 它只是减少对象的引用计数,如果计数达到零才会调用 __del__() 。

如果你的数据结构包含循环链接(如树每个子节点都带有父节点的引用,而每个父节点也带有子节点的列表),引用计数永远不会回零。 尽管 Python 偶尔会用某种算法检测这种循环引用,但在数据结构的最后一条引用消失之后,垃圾收集器可能还要过段时间才会运行,因此 __del__() 方法可能会在不方便或随机的时刻被调用。 这对于重现一个问题是非常不方便的。 更糟糕的是,各个对象的 __del__() 方法是以随机顺序执行的。 虽然你可以运行 gc.collect() 来强制执行垃圾回收操作,但 仍会存在 一些对象永远不会被回收的失控情况。

尽管有垃圾回收器,但当对象使用完毕时在要调用的对象上定义显式的 close() 方法仍然是个好主意。 close() 方法可以随后移除引用子对象的属性。 请不要直接调用 __del__() -- __del__() 应当调用 close() 并且 close() 应当确保被可以被同一对象多次调用。

另一种避免循环引用的做法是利用 weakref 模块,该模块允许指向对象但不增加其引用计数。例如,树状数据结构应该对父节点和同级节点使用弱引用(如果真要用的话!)

最后,如果你的 __del__() 方法引发了异常,会将警告消息打印到 sys.stderr 。

如何获取给定类的所有实例的列表? ¶

Python 不会记录类(或内置类型)的实例。可以在类的构造函数中编写代码,通过保留每个实例的弱引用列表来跟踪所有实例。

为什么 id() 的结果看起来不是唯一的? ¶

id() 返回一个整数,该整数在对象的生命周期内保证是唯一的。 因为在 CPython 中,这是对象的内存地址,所以经常发生在从内存中删除对象之后,下一个新创建的对象被分配在内存中的相同位置。 这个例子说明了这一点:

这两个 id 属于不同的整数对象,之前先创建了对象,执行 id() 调用后又立即被删除了。若要确保检测 id 时的对象仍处于活动状态,请再创建一个对该对象的引用:

我什麼時候可以依靠 is 運算子進行識別性測試? ¶

is 運算子測試物件識別性。測試 a is b 等同於 id(a) == id(b) 。

識別性測試最重要的屬性是物件始終與自身相同, a is a 總是回傳 True 。識別性測試通常比相等性測試更快。與相等性測試不同,識別性測試保證回傳布林值 True 或 False 。

然而,* 只有* 當物件識別性得到保證時,識別性測試才能代替相等性測試。一般來說,保證識別性的情況有以下三種:

1) Assignments create new names but do not change object identity. After the assignment new = old , it is guaranteed that new is old .

2) Putting an object in a container that stores object references does not change object identity. After the list assignment s[0] = x , it is guaranteed that s[0] is x .

3) 单例对象,也即该对象只能存在一个实例。在赋值操作 a = None 和 b = None 之后,可以保证 a is b ,因为 None 是单例对象。

在大多數其他情況下,識別性測試是不可取的,相等性測試是首選。特別是,識別性測試不應用於檢查常數,例如不能保證是單例的 int 和 str :

同样地,可变容器的新实例,对象身份一定不同:

在標準函式庫程式碼中,你將看到幾種正確使用識別性測試的常見模式:

1) As recommended by PEP 8 , an identity test is the preferred way to check for None . This reads like plain English in code and avoids confusion with other objects that may have boolean values that evaluate to false.

2) Detecting optional arguments can be tricky when None is a valid input value. In those situations, you can create a singleton sentinel object guaranteed to be distinct from other objects. For example, here is how to implement a method that behaves like dict.pop() :

3) Container implementations sometimes need to augment equality tests with identity tests. This prevents the code from being confused by objects such as float('NaN') that are not equal to themselves.

例如,以下是 collections.abc.Sequence.__contains__() 的實作:

子類別如何控制不可變實例中存儲的資料? ¶

当子类化一个不可变类型时,请重写 __new__() 方法而不是 __init__() 方法。 后者只在一个实例被创建 之后 运行,这对于改变不可变实例中的数据来说太晚了。

所有这些不可变的类都有一个与它们的父类不同的签名:

這些類別可以像這樣使用:

我该如何缓存方法调用? ¶

缓存方法的两个主要工具是 functools.cached_property() 和 functools.lru_cache() 。 前者在实例层级上存储结果而后者在类层级上存储结果。

cached_property 方式仅适用于不接受任何参数的方法。 它不会创建对实例的引用。 被缓存的方法结果将仅在实例的生存其内被保留。

其优点是,当一个实例不再被使用时,缓存的方法结果将被立即释放。缺点是,如果实例累积起来,累积的方法结果也会增加。它们可以无限制地增长。

lru_cache 方法適用於具有 可雜湊 引數的方法。除非特別努力傳遞弱引用,否則它會建立對實例的引用。

最少近期使用算法的优点是缓存会受指定的 maxsize 限制。 它的缺点是实例会保持存活,直到其达到生存期或者缓存被清空。

这个例子演示了几种不同的方式:

上面的例子假定 station_id 从不改变。 如果相关实例属性是可变对象,则 cached_property 方式就不再适用,因为它无法检测到属性的改变。

要让 lru_cache 方式在 station_id 可变时仍然适用,类需要定义 __eq__() 和 __hash__() 方法以便缓存能检测到相关属性的更新:

如何创建 .pyc 文件? ¶

当首次导入模块时(或当前已编译文件创建之后源文件发生了改动),在 .py 文件所在目录的 __pycache__ 子目录下会创建一个包含已编译代码的 .pyc 文件。该 .pyc 文件的名称开头部分将与 .py 文件名相同,并以 .pyc 为后缀,中间部分则依据创建它的 python 版本而各不相同。(详见 PEP 3147 。)

.pyc 文件有可能会无法创建,原因之一是源码文件所在的目录存在权限问题,这样就无法创建 __pycache__ 子目录。假如以某个用户开发程序而以另一用户运行程序,就有可能发生权限问题,测试 Web 服务器就属于这种情况。

除非设置了 PYTHONDONTWRITEBYTECODE 环境变量,否则导入模块并且 Python 能够创建 __pycache__ 子目录并把已编译模块写入该子目录(权限、存储空间等等)时,.pyc 文件就将自动创建。

在最高层级运行的 Python 脚本不会被视为经过了导入操作,因此不会创建 .pyc 文件。假定有一个最高层级的模块文件 foo.py ,它导入了另一个模块 xyz.py ,当运行 foo 模块(通过输入 shell 命令 python foo.py ),则会为 xyz 创建一个 .pyc ,因为 xyz 是被导入的,但不会为 foo 创建 .pyc 文件,因为 foo.py 不是被导入的。

若要为 foo 创建 .pyc 文件 —— 即为未做导入的模块创建 .pyc 文件 —— 可以利用 py_compile 和 compileall 模块。

py_compile 模块能够手动编译任意模块。 一种做法是交互式地使用该模块中的 compile() 函数:

这将会将 .pyc 文件写入与 foo.py 相同位置下的 __pycache__ 子目录(或者你也可以通过可选参数 cfile 来重写该行为)。

还可以用 compileall 模块自动编译一个或多个目录下的所有文件。只要在命令行提示符中运行 compileall.py 并给出要编译的 Python 文件所在目录路径即可:

如何找到当前模块名称? ¶

模块可以查看预定义的全局变量 __name__ 获悉自己的名称。如其值为 '__main__' ,程序将作为脚本运行。通常,许多通过导入使用的模块同时也提供命令行接口或自检代码,这些代码只在检测到处于 __name__ 之后才会执行:

如何让模块相互导入? ¶

问题是解释器将执行以下步骤:

为 foo 创建空的全局变量

编译 foo 并开始执行

为 bar 创建空的全局变量

bar 已被編譯並開始執行

bar 导入 foo (该步骤无操作,因为已经有一个名为 foo 的模块)。

导入机制尝试从 foo_var 全局变量读取 foo ,用来设置 bar.foo_var = foo.foo_var

最后一步失败了,因为 Python 还没有完成对 foo 的解释,foo 的全局符号字典仍然是空的。

当你使用 import foo ,然后尝试在全局代码中访问 foo.foo_var 时,会发生同样的事情。

此問題有(至少)三種可能的解決方法。

Guido van Rossum 建议完全避免使用 from <module> import ... ,并将所有代码放在函数中。全局变量和类变量的初始化只应使用常量或内置函数。这意味着导入模块中的所有内容都以 <module>.<name> 的形式引用。

Jim Roskind 建議在每個模組中按以下順序執行各個步驟:

导出(全局变量、函数和不需要导入基类的类)

活躍程式碼(包括從引入值初始化的全域變數)。

Van Rossum 不太喜欢这种方法,因为import出现在一个奇怪的地方,但它确实有效。

Matthias Urlichs 建議重構你的程式碼,以便打從一開始就不需要遞迴引入。

__import__('x.y.z') 回傳 <module 'x'>,那我怎麼得到 z? ¶

不妨考虑换用 importlib 中的函数 import_module() :

當我編輯需要引入的模組並重新引入它時,更動沒有反應出來。為什麼會這樣? ¶

出于效率和一致性的原因,Python 仅在第一次导入模块时读取模块文件。否则,在一个多模块的程序中,每个模块都会导入相同的基础模块,那么基础模块将会被一而再、再而三地解析。如果要强行重新读取已更改的模块,请执行以下操作:

警告:这种技术并非万无一失。尤其是模块包含了以下语句时:

仍将继续使用前一版的导入对象。如果模块包含了类的定义,并 不会 用新的类定义更新现有的类实例。这样可能会导致以下矛盾的行为:

如果印出類別物件的「識別性」,問題的本質就很清楚了:

一般的 Python 常見問答集

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications You must be signed in to change notification settings

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnboundLocalError: local variable 'movie_frames' referenced before assignment #117

@swumagic

swumagic commented Nov 10, 2023 • edited

  • 👍 1 reaction

@AlexVelger

AlexVelger commented Dec 3, 2023

Sorry, something went wrong.

No branches or pull requests

@AlexVelger

COMMENTS

  1. Python 3: UnboundLocalError: local variable referenced before assignment

    File "weird.py", line 5, in main. print f(3) UnboundLocalError: local variable 'f' referenced before assignment. Python sees the f is used as a local variable in [f for f in [1, 2, 3]], and decides that it is also a local variable in f(3). You could add a global f statement: def f(x): return x. def main():

  2. How to Fix

    Output. Hangup (SIGHUP) Traceback (most recent call last): File "Solution.py", line 7, in <module> example_function() File "Solution.py", line 4, in example_function x += 1 # Trying to modify global variable 'x' without declaring it as global UnboundLocalError: local variable 'x' referenced before assignment Solution for Local variable Referenced Before Assignment in Python

  3. Local variable referenced before assignment in Python

    If a variable is assigned a value in a function's body, it is a local variable unless explicitly declared as global. # Local variables shadow global ones with the same name You could reference the global name variable from inside the function but if you assign a value to the variable in the function's body, the local variable shadows the global one.

  4. How to fix UnboundLocalError: local variable 'x' referenced before

    The UnboundLocalError: local variable 'x' referenced before assignment occurs when you reference a variable inside a function before declaring that variable. To resolve this error, you need to use a different variable name when referencing the existing variable, or you can also specify a parameter for the function. I hope this tutorial is useful.

  5. Python UnboundLocalError: local variable referenced before assignment

    UnboundLocalError: local variable referenced before assignment. Example #1: Accessing a Local Variable. Solution #1: Passing Parameters to the Function. Solution #2: Use Global Keyword. Example #2: Function with if-elif statements. Solution #1: Include else statement. Solution #2: Use global keyword. Summary.

  6. UnboundLocalError Local variable Referenced Before Assignment in Python

    Avoid Reassignment of Global Variables. Below, code calculates a new value (local_var) based on the global variable and then prints both the local and global variables separately.It demonstrates that the global variable is accessed directly without being reassigned within the function.

  7. [SOLVED] Local Variable Referenced Before Assignment

    Local Variables Global Variables; A local variable is declared primarily within a Python function.: Global variables are in the global scope, outside a function. A local variable is created when the function is called and destroyed when the execution is finished.

  8. Fixing Python UnboundLocalError: Local Variable 'x' Accessed Before

    2 Solutions for the Problem. 2.1 Method 1: Initializing the Variable. 2.2 Method 2: Using Global Variables. 2.3 Method 3: Using Nonlocal Variables.

  9. Python local variable referenced before assignment Solution

    Trying to assign a value to a variable that does not have local scope can result in this error: UnboundLocalError: local variable referenced before assignment. Python has a simple rule to determine the scope of a variable. If a variable is assigned in a function, that variable is local. This is because it is assumed that when you define a ...

  10. Local (?) variable referenced before assignment

    In order for you to modify test1 while inside a function you will need to do define test1 as a global variable, for example: test1 = 0. def test_func(): global test1. test1 += 1. test_func() However, if you only need to read the global variable you can print it without using the keyword global, like so: test1 = 0.

  11. Python 3: UnboundLocalError: local variable referenced before assignment

    To fix this, you can either move the assignment of the variable x before the print statement, or give it an initial value before the print statement. def example (): x = 5 print (x) example()

  12. 【Python】成功解决UnboundLocalError: local variable 'a' referenced before

    下滑查看解决方法 一、什么是UnboundLocalError? 在Python编程中,UnboundLocalError: local variable 'a' referenced before assignment这个错误常常让初学者感到困惑。这个错误表明你尝试在一个函数内部引用了一个局部变量,但是在引用之前并没有对它进行赋值。

  13. UnboundLocalError: local variable referenced before assignment

    I have following simple function to get percent values for different cover types from a raster. It gives me following error: UnboundLocalError: local variable 'a' referenced before assignment whic...

  14. UnboundLocalError: local variable 'active_adapters' referenced before

    ) from peft. tuners. tuners_utils import BaseTunerLayer for _, module in self. named_modules (): if isinstance (module, BaseTunerLayer): active_adapters = module. active_adapter break # For previous PEFT versions > if isinstance (active_adapters, str): E UnboundLocalError: local variable 'active_adapters' referenced before assignment

  15. How to resolve UnboundLocalError: local variable referenced before

    Another UnboundLocalError: local variable referenced before assignment Issue 2 global var becomes local --UnboundLocalError: local variable referenced before assignment

  16. [Bug]: UnboundLocalError: local variable 'lora_b_k' referenced before

    Legend: X = Self SYS = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI) NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node PHB = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU) PXB = Connection traversing multiple ...

  17. UndboundLocalError: local variable referenced before assignment

    UndboundLocalError: local variable referenced before assignment. Coding. MarcelloSilvestre February 29, 2024, 12:17pm 1. Hello all, I'm using PsychoPy 2023.2.3 Win 10 x64bits. I am having a few issues in my experiment, some of the errors I never saw in older versions of Psychopy ... "UnboundLocalError: local variable 'os' referenced before ...

  18. UnboundLocalError: local variable 'all_files' referenced before

    UnboundLocalError: local variable 'all_files' referenced before assignment #691. Open HenryZhuHR opened this issue Apr 27, 2024 · 1 comment Open ... request_exception UnboundLocalError: local variable ' all_files ' referenced before assignment ...

  19. UnboundLocalError: local variable … referenced before assignment

    UnboundLocalError: local variable … referenced before assignment [duplicate] Ask Question Asked 10 years ... (secret, hash_data, sha512)) UnboundLocalError: local variable 'hmac' referenced before assignment. Somebody knows why? Thanks. python; python-2.7; Share. Follow edited Jun 13, 2013 at 21:22. user2480235. asked Jun 13, 2013 at ...

  20. 程式開發常見問答集

    UnboundLocalError: local variable 'x' referenced before assignment 原因就是,当对某作用域内的变量进行赋值时,该变量将成为该作用域内的局部变量,并覆盖外部作用域中的同名变量。

  21. UnboundLocalError: local variable 'movie_frames' referenced before

    UnboundLocalError: local variable 'movie_frames' referenced before assignment #117. swumagic opened this issue Nov 10, 2023 · 1 comment Comments. Copy link swumagic commented Nov 10, 2023 • ... UnboundLocalError: local variable 'movie_frames' referenced before assignment

  22. python

    The issue here seems to be the variable scope. In the function the variable rev_get_event is local to the scope of the function. If you mean the global variable the function should explicitly declare it, for example as follows: global rev_get_event def Get_event (username, password, eventID): global rev_get_event try: payload = {'username ...

  23. Getting UnboundLocalError in python scrapy framework

    UnboundLocalError: local variable referenced before assignment when reading from file - same problem: variable is only set conditionally - wjandrea. Mar 31, 2020 at 17:55. ... "UnboundLocalError: local variable referenced before assignment" after an if statement. Related. 12907. What does the "yield" keyword do in Python?

  24. unboundlocalerror when running a script on the server Python

    Ask questions, find answers and collaborate at work with Stack Overflow for Teams. Explore Teams Create a free Team