Fix "local variable referenced before assignment" in Python

python local variable might be referenced before assignment

Introduction

If you're a Python developer, you've probably come across a variety of errors, like the "local variable referenced before assignment" error. This error can be a bit puzzling, especially for beginners and when it involves local/global variables.

Today, we'll explain this error, understand why it occurs, and see how you can fix it.

The "local variable referenced before assignment" Error

The "local variable referenced before assignment" error in Python is a common error that occurs when a local variable is referenced before it has been assigned a value. This error is a type of UnboundLocalError , which is raised when a local variable is referenced before it has been assigned in the local scope.

Here's a simple example:

Running this code will throw the "local variable 'x' referenced before assignment" error. This is because the variable x is referenced in the print(x) statement before it is assigned a value in the local scope of the foo function.

Even more confusing is when it involves global variables. For example, the following code also produces the error:

But wait, why does this also produce the error? Isn't x assigned before it's used in the say_hello function? The problem here is that x is a global variable when assigned "Hello ". However, in the say_hello function, it's a different local variable, which has not yet been assigned.

We'll see later in this Byte how you can fix these cases as well.

Fixing the Error: Initialization

One way to fix this error is to initialize the variable before using it. This ensures that the variable exists in the local scope before it is referenced.

Let's correct the error from our first example:

In this revised code, we initialize x with a value of 1 before printing it. Now, when you run the function, it will print 1 without any errors.

Fixing the Error: Global Keyword

Another way to fix this error, depending on your specific scenario, is by using the global keyword. This is especially useful when you want to use a global variable inside a function.

No spam ever. Unsubscribe anytime. Read our Privacy Policy.

Here's how:

In this snippet, we declare x as a global variable inside the function foo . This tells Python to look for x in the global scope, not the local one . Now, when you run the function, it will increment the global x by 1 and print 1 .

Similar Error: NameError

An error that's similar to the "local variable referenced before assignment" error is the NameError . This is raised when you try to use a variable or a function name that has not been defined yet.

Running this code will result in a NameError :

In this case, we're trying to print the value of y , but y has not been defined anywhere in the code. Hence, Python raises a NameError . This is similar in that we are trying to use an uninitialized/undefined variable, but the main difference is that we didn't try to initialize y anywhere else in our code.

Variable Scope in Python

Understanding the concept of variable scope can help avoid many common errors in Python, including the main error of interest in this Byte. But what exactly is variable scope?

In Python, variables have two types of scope - global and local. A variable declared inside a function is known as a local variable, while a variable declared outside a function is a global variable.

Consider this example:

In this code, x is a global variable, and y is a local variable. x can be accessed anywhere in the code, but y can only be accessed within my_function . Confusion surrounding this is one of the most common causes for the "variable referenced before assignment" error.

In this Byte, we've taken a look at the "local variable referenced before assignment" error and another similar error, NameError . We also delved into the concept of variable scope in Python, which is an important concept to understand to avoid these errors. If you're seeing one of these errors, check the scope of your variables and make sure they're being assigned before they're being used.

python local variable might be referenced before assignment

Monitor with Ping Bot

Reliable monitoring for your app, databases, infrastructure, and the vendors they rely on. Ping Bot is a powerful uptime and performance monitoring tool that helps notify you and resolve issues before they affect your customers.

OpenAI

© 2013- 2024 Stack Abuse. All rights reserved.

How to Fix Local Variable Referenced Before Assignment Error in Python

How to Fix Local Variable Referenced Before Assignment Error in Python

Table of Contents

Fixing local variable referenced before assignment error.

In Python , when you try to reference a variable that hasn't yet been given a value (assigned), it will throw an error.

That error will look like this:

In this post, we'll see examples of what causes this and how to fix it.

Let's begin by looking at an example of this error:

If you run this code, you'll get

The issue is that in this line:

We are defining a local variable called value and then trying to use it before it has been assigned a value, instead of using the variable that we defined in the first line.

If we want to refer the variable that was defined in the first line, we can make use of the global keyword.

The global keyword is used to refer to a variable that is defined outside of a function.

Let's look at how using global can fix our issue here:

Global variables have global scope, so you can referenced them anywhere in your code, thus avoiding the error.

If you run this code, you'll get this output:

In this post, we learned at how to avoid the local variable referenced before assignment error in Python.

The error stems from trying to refer to a variable without an assigned value, so either make use of a global variable using the global keyword, or assign the variable a value before using it.

Thanks for reading!

python local variable might be referenced before assignment

  • Privacy Policy
  • Terms of Service

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

[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

Local VariablesGlobal Variables
A 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.A Variable is created upon execution and exists in memory till the program stops.
Local Variables can only be accessed within their own function.All functions of the program can access global variables.
Local variables are immune to changes in the global scope. Thereby being more secure.Global Variables are less safer from manipulation as they are accessible in the global scope.

[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

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

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

How to reproduce this error

How to fix this error.

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

Take your skills to the next level ⚡️

python local variable might be 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

Local variable referenced before assignment in Python

The “local variable referenced before assignment” error occurs when you try to use a local variable before it has been assigned a value. This is a general programming concept describing the situation typically arises in situations where you declare a variable within a function but then try to access or modify it before actually assigning a value to it.

In Python, the compiler might throw the exact error: “UnboundLocalError: cannot access local variable ‘x’ where it is not associated with a value”

Here’s an example to illustrate this error:

In this example, you would encounter the above error because you’re trying to print the value of x before it has been assigned a value. To fix this, you should assign a value to x before attempting to access it:

In the corrected version, the local variable x is assigned a value before it’s used, preventing the error.

Keep in mind that Python treats variables inside functions as local unless explicitly stated otherwise using the global keyword (for global variables) or the nonlocal keyword (for variables in nested functions).

If you encounter this error and you’re sure that the variable should have been assigned a value before its use, double-check your code for any logical errors or typos that might be causing the variable to not be assigned properly.

Using the global keyword

If you have a global variable named letter and you try to modify it inside a function without declaring it as global, you will get error.

This is because Python assumes that any variable that is assigned a value inside a function is a local variable, unless you explicitly tell it otherwise.

To fix this error, you can use the global keyword to indicate that you want to use the global variable:

Using nonlocal keyword

The nonlocal keyword is used to work with variables inside nested functions, where the variable should not belong to the inner function. It allows you to modify the value of a non-local variable in the outer scope.

For example, if you have a function outer that defines a variable x , and another function inner inside outer that tries to change the value of x , you need to use the nonlocal keyword to tell Python that you are referring to the x defined in outer , not a new local variable in inner .

Here is an example of how to use the nonlocal keyword:

If you don’t use the nonlocal keyword, Python will create a new local variable x in inner , and the value of x in outer will not be changed:

You might also like

How to Solve Error - Local Variable Referenced Before Assignment in Python

  • Python How-To's
  • How to Solve Error - Local Variable …

Check the Variable Scope to Fix the local variable referenced before assignment Error in Python

Initialize the variable before use to fix the local variable referenced before assignment error in python, use conditional assignment to fix the local variable referenced before assignment error in python.

How to Solve Error - Local Variable Referenced Before Assignment in Python

This article delves into various strategies to resolve the common local variable referenced before assignment error. By exploring methods such as checking variable scope, initializing variables before use, conditional assignments, and more, we aim to equip both novice and seasoned programmers with practical solutions.

Each method is dissected with examples, demonstrating how subtle changes in code can prevent this frequent error, enhancing the robustness and readability of your Python projects.

The local variable referenced before assignment occurs when some variable is referenced before assignment within a function’s body. The error usually occurs when the code is trying to access the global variable.

The primary purpose of managing variable scope is to ensure that variables are accessible where they are needed while maintaining code modularity and preventing unexpected modifications to global variables.

We can declare the variable as global using the global keyword in Python. Once the variable is declared global, the program can access the variable within a function, and no error will occur.

The below example code demonstrates the code scenario where the program will end up with the local variable referenced before assignment error.

In this example, my_var is a global variable. Inside update_var , we attempt to modify it without declaring its scope, leading to the Local Variable Referenced Before Assignment error.

We need to declare the my_var variable as global using the global keyword to resolve this error. The below example code demonstrates how the error can be resolved using the global keyword in the above code scenario.

In the corrected code, we use the global keyword to inform Python that my_var references the global variable.

When we first print my_var , it displays the original value from the global scope.

After assigning a new value to my_var , it updates the global variable, not a local one. This way, we effectively tell Python the scope of our variable, thus avoiding any conflicts between local and global variables with the same name.

python local variable referenced before assignment - output 1

Ensure that the variable is initialized with some value before using it. This can be done by assigning a default value to the variable at the beginning of the function or code block.

The main purpose of initializing variables before use is to ensure that they have a defined state before any operations are performed on them. This practice is not only crucial for avoiding the aforementioned error but also promotes writing clear and predictable code, which is essential in both simple scripts and complex applications.

In this example, the variable total is used in the function calculate_total without prior initialization, leading to the Local Variable Referenced Before Assignment error. The below example code demonstrates how the error can be resolved in the above code scenario.

In our corrected code, we initialize the variable total with 0 before using it in the loop. This ensures that when we start adding item values to total , it already has a defined state (in this case, 0).

This initialization is crucial because it provides a starting point for accumulation within the loop. Without this step, Python does not know the initial state of total , leading to the error.

python local variable referenced before assignment - output 2

Conditional assignment allows variables to be assigned values based on certain conditions or logical expressions. This method is particularly useful when a variable’s value depends on certain prerequisites or states, ensuring that a variable is always initialized before it’s used, thereby avoiding the common error.

In this example, message is only assigned within the if and elif blocks. If neither condition is met (as with guest ), the variable message remains uninitialized, leading to the Local Variable Referenced Before Assignment error when trying to print it.

The below example code demonstrates how the error can be resolved in the above code scenario.

In the revised code, we’ve included an else statement as part of our conditional logic. This guarantees that no matter what value user_type holds, the variable message will be assigned some value before it is used in the print function.

This conditional assignment ensures that the message is always initialized, thereby eliminating the possibility of encountering the Local Variable Referenced Before Assignment error.

python local variable referenced before assignment - output 3

Throughout this article, we have explored multiple approaches to address the Local Variable Referenced Before Assignment error in Python. From the nuances of variable scope to the effectiveness of initializations and conditional assignments, these strategies are instrumental in developing error-free code.

The key takeaway is the importance of understanding variable scope and initialization in Python. By applying these methods appropriately, programmers can not only resolve this specific error but also enhance the overall quality and maintainability of their code, making their programming journey smoother and more rewarding.

  • 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

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?

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)

Adventures in Machine Learning

4 ways to fix local variable referenced before assignment error in python, resolving the local variable referenced before assignment error in python.

Python is one of the world’s most popular programming languages due to its simplicity, readability, and versatility. Despite its many advantages, when coding in Python, one may encounter various errors, with the most common being the “local variable referenced before assignment” error.

Even the most experienced Python developers have encountered this error at some point in their programming career. In this article, we will look at four effective strategies for resolving the local variable referenced before assignment error in Python.

Strategy 1: Assigning a Value before Referencing

The first strategy is to assign a value to a variable before referencing it. The error occurs when the variable is referenced before it is assigned a value.

This problem can be avoided by initializing the variable before referencing it. For example, let us consider the snippet below:

“`python

add_numbers():

print(x + y)

add_numbers()

In the snippet above, the variables `x` and `y` are not assigned values before they are referenced in the `print` statement. Therefore, we will get a local variable “referenced before assignment” error.

To resolve this error, we must initialize the variables before referencing them. We can avoid this error by assigning a value to `x` and `y` before they are referenced, as shown below:

Strategy 2: Using the Global Keyword

In Python, variables declared inside a function are considered local variables. Thus, they are separate from other variables declared outside of the function.

If we want to use a variable outside of the function, we must use the global keyword. Using the global keyword tells Python that you want to use the variable that was defined globally, not locally.

For example:

In the code snippet above, the `global` keyword tells Python to use the variable `x` defined outside of the function rather than a local variable named `x`. Thus, Python will output 30.

Strategy 3: Adding Input Parameters for Functions

Another way to avoid the local variable referenced before assignment error is by adding input parameters to functions.

def add_numbers(x, y):

add_numbers(10, 20)

In the code snippet above, `x` and `y` are variables that are passed into the `add_numbers` function as arguments.

This approach allows us to avoid the local variable referenced before assignment error because the variables are being passed into the function as input parameters. Strategy 4: Initializing Variables before Loops or Conditionals

Finally, it’s also a good practice to initialize the variables before loops or conditionals.

If you are defining a variable within a loop, you must initialize it before the loop starts. This way, the variable already exists, and we can update the value inside the loop.

my_list = [1, 2, 3, 4, 5]

for number in my_list:

sum += number

In the code snippet above, the variable `sum` has been initialized with the value of 0 before the loop runs. Thus, we can update and use the variable inside the loop.

In conclusion, the “local variable referenced before assignment” error is a common issue in Python. However, with the strategies discussed in this article, you can avoid the error and write clean Python code.

Remember to initialize your variables, use the global keyword, add input parameters in functions, and initialize variables before loops or conditionals. By following these techniques, your Python code will be error-free and much easier to manage.

In essence, this article has provided four key strategies for resolving the “local variable referenced before assignment” error that is common in Python. These strategies include initializing variables before referencing, using the global keyword, adding input parameters to functions, and initializing variables before loops or conditionals.

These techniques help to ensure clean code that is free from errors. By implementing these strategies, developers can improve their code quality and avoid time-wasting errors that can occur in their work.

Popular Posts

Mastering list splitting techniques in python, 7 sql podcasts to help you master sql learning, preventing unicodedecodeerror: solutions for python programmers.

  • Terms & Conditions
  • Privacy Policy

w3docs logo

  • Password Generator
  • HTML Editor
  • HTML Encoder
  • JSON Beautifier
  • CSS Beautifier
  • Markdown Convertor
  • Find the Closest Tailwind CSS Color
  • Phrase encrypt / decrypt
  • Browser Feature Detection
  • Number convertor
  • CSS Maker text shadow
  • CSS Maker Text Rotation
  • CSS Maker Out Line
  • CSS Maker RGB Shadow
  • CSS Maker Transform
  • CSS Maker Font Face
  • Color Picker
  • Colors CMYK
  • Color mixer
  • Color Converter
  • Color Contrast Analyzer
  • Color Gradient
  • String Length Calculator
  • MD5 Hash Generator
  • Sha256 Hash Generator
  • String Reverse
  • URL Encoder
  • URL Decoder
  • Base 64 Encoder
  • Base 64 Decoder
  • Extra Spaces Remover
  • String to Lowercase
  • String to Uppercase
  • Word Count Calculator
  • Empty Lines Remover
  • HTML Tags Remover
  • Binary to Hex
  • Hex to Binary
  • Rot13 Transform on a String
  • String to Binary
  • Duplicate Lines Remover

Python 3: UnboundLocalError: local variable referenced before assignment

This error occurs when you are trying to access a variable before it has been assigned a value. Here is an example of a code snippet that would raise this error:

Watch a video course Python - The Practical Guide

The error message will be:

In this example, the variable x is being accessed before it is assigned a value, which is causing the error. 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.

Both will work without any error.

Related Resources

  • Using global variables in a function
  • "Least Astonishment" and the Mutable Default Argument
  • Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?
  • HTML Basics
  • Javascript Basics
  • TypeScript Basics
  • React Basics
  • Angular Basics
  • Sass Basics
  • Vue.js Basics
  • Python Basics
  • Java Basics
  • NodeJS Basics

Consultancy

  • Technology Consulting
  • Customer Experience Consulting
  • Solution Architect Consulting

Software Development Services

  • Ecommerce Development
  • Web App Development
  • Mobile App Development
  • SAAS Product Development
  • Content Management System
  • System Integration & Data Migration
  • Cloud Computing
  • Computer Vision

Dedicated Development Team

  • Full Stack Developers For Hire
  • Offshore Development Center

Marketing & Creative Design

  • UX/UI Design
  • Customer Experience Optimization
  • Digital Marketing
  • Devops Services
  • Service Level Management
  • Security Services
  • Odoo gold partner

By Industry

  • Retail & Ecommerce
  • Manufacturing
  • Import & Distribution
  • Financical & Banking
  • Technology For Startups

Business Model

  • MARKETPLACE ECOMMERCE

Our realized projects

python local variable might be referenced before assignment

MB Securities - A Premier Brokerage

python local variable might be referenced before assignment

iONAH - A Pioneer in Consumer Electronics Industry

python local variable might be referenced before assignment

Emers Group - An Official Nike Distributing Agent

python local variable might be referenced before assignment

Academy Xi - An Australian-based EdTech Startup

  • Market insight

python local variable might be referenced before assignment

  • Ohio Digital
  • Onnet Consoulting

></center></p><h2>Local variable referenced before assignment: The UnboundLocalError in Python</h2><p>When you start introducing functions into your code, you’re bound to encounter an UnboundLocalError at some point. Because you try to use a local variable referenced before assignment. So, in this guide, we talk about what this error means and why it is raised. We walk through an example in action to help you understand how you can solve it.</p><p>Source: careerkarma</p><p><center><img style=

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. To clarify, a variable is assigned in a function, that variable is local. 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. Whereas, local variables are only accessible within the function in which they are originally defined.

An example of Local variable referenced before assignment

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

Firstly, 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”. Then, 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 of Local variable referenced before assignment and see what happens:

Here is an error!

The Solution of Local variable referenced before assignment

The code returns an error: Unboundlocalerror local variable referenced before assignment 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.

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

Therefore, this problem of variable referenced before assignment could be solved in two ways. Firstly, 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. This approach is good because it lets us keep “letter” in the local context. To clarify, we could even remove the “letter = “F”” statement from the top of our code because we do not use it in the global context.

Alternatively, we could use the “global” keyword to make our global keyword available in the local context in our  calculate_grade()  function:

We use the “global” keyword at the start of our function.

This keyword changes the scope of our variable to a global variable. This means the “return” statement will no longer treat “letter” like a local variable. Let’s run our code. Our code returns: F.

The code works successfully! Let’s try it using a different grade number by setting the value of “numerical” to a new number:

Our code returns: B.

Finally, we have fixed the local variable referenced before assignment error in the code.

To sum up, as you can see, 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. Then, you can solve this error by ensuring that a local variable is declared before you assign it a value. Moreover, if a variable is declared globally that you want to access in a function, you can use the “global” keyword to change its value. In case you have any inquiry, let’s CONTACT US . With a lot of experience in Mobile app development services , we will surely solve it for you instantly.

>>> Read more

  • Average python length: How to find it with examples
  • List assignment index out of range: Python indexerror solution you should know
  • Spyder vs Pycharm: The detailed comparison to get best option for Python programming
  • fix python error , Local variable referenced before assignment , python , python dictionary , python error , python learning , UnboundLocalError , UnboundLocalError in Python

Our Other Services

  • E-commerce Development
  • Web Apps Development
  • Web CMS Development
  • Mobile Apps Development
  • Software Consultant & Development
  • System Integration & Data Migration
  • Dedicated Developers & Testers For Hire
  • Remote Working Team
  • Saas Products Development
  • Web/Mobile App Development
  • Outsourcing
  • Hiring Developers
  • Digital Transformation
  • Advanced SEO Tips

Offshore Development center

Lastest News

aws-cloud-managed-services

Challenges and Advices When Using AWS Cloud Managed Services

aws-well-architected-framework

Comprehensive Guide about AWS Well Architected Framework

aws-cloud-migration

AWS Cloud Migration: Guide-to-Guide from A to Z

cloud computing for healthcare

Uncover The Treasures Of Cloud Computing For Healthcare 

cloud computing in financial services

A Synopsis of Cloud Computing in Financial Services 

applications of cloud computing

Discover Cutting-Edge Cloud Computing Applications To Optimize Business Resources

Tailor your experience

  • Success Stories

Copyright ©2007 – 2021 by AHT TECH JSC. All Rights Reserved.

python local variable might be referenced before assignment

Thank you for your message. It has been sent.

Local variable referenced before assignment in Python

In Python, while working with functions, you can encounter various types of errors. A common error when working with the functions is “ Local variable referenced before assignment ”. The stated error occurs when a local variable is referenced before being assigned any value.

This write-up will provide the possible reasons and the appropriate solutions to the error “Local variable referenced before assignment” with practical examples. The following aspects are discussed in this write-up in detail:

Reason: Reference a Local Variable

Solution 1: mark the variable globally, solution 2: using function parameter value, solution 3: using nonlocal keyword.

The main reason for the “ local variable referenced before assignment ” error in Python is using a variable that does not have local scope. This also means referencing a local variable without assigning it a value in a function.

The variable initialized inside the function will only be accessed inside the function, and these variables are known as local variables. To use variables in the entire program, variables must be initialized globally. The below example illustrates how the “ UnboundLocalError ” occurs in Python.

python local variable might be referenced before assignment

In the above snippet, the “ Student ” variable is not marked as global, so when it is accessed inside the function, the Python interpreter returns an error.

Note: We can access the outer variable inside the function, but when the new value is assigned to a variable, the “UnboundLocalError” appears on the screen.

To solve this error, we must mark the “ Student ” variable as a global variable using the keyword “ global ” inside the function.

Within the function, we can assign a new value to the student variable without any error. Let’s have a look at the below snippet for a detailed understanding:

In the above code, the local variable is marked as a “ global ” variable inside the function. We can easily reference the variable before assigning the variable in the program.

python local variable might be referenced before assignment

The above snippet proves that the global keyword resolves the “unboundLocalError”.

Passing a value as an argument to the function will also resolve the stated error. The function accepts the variable as an argument and uses the argument value inside the function. Let’s have a look at the given below code block for a better understanding:

In the above code, the variable is referenced before assigning the value inside the user-defined function. The program executes successfully without any errors because the variable is passed as a parameter value of the function.

python local variable might be referenced before assignment

The above output shows the value of the function when the function is accessed in the program without any “ Local Variable referenced ” error.

The “ nonlocal ” keyword is utilized in the program to assign a new value to a local variable of function in the nested function. Here is an example of code:

In the above code, the keyword “ nonlocal ” is used to mark the local variable of the outer function as nonlocal. After making the variable nonlocal, we can reference it before assigning a value without any error.

python local variable might be referenced before assignment

The above output shows the value of the inner function without any “ local variable referenced ” error in a program.

The “ Local variable referenced before assignment ” appears in Python due to assigning a value to a variable that does not have a local scope. To fix this error, the global keyword, return statement, and nonlocal nested function is used in Python script. The global keywords are used with variables to make it able to access inside and outside the function. The return statement is also used to return the variable’s new value back to function and display the result on the screen. This Python guide presented a detailed overview of the reason and solutions for the error “Local variable referenced before assignment” in Python.

Joseph

Get the Reddit app

Subreddit for posting questions and asking for general advice about your python code.

Local variable referenced before assignment?

This is a piece of code i made for a project to mimic an ATM like machine, this is just the start of it (inputting the pin and accessing balance and other things) . and im wondering why it all works until i input the wrong integer for the pin, thats when it gives me 'UnboundLocalError: local variable 'attempts' referenced before assignment' any ideas?

pin = 4882 import time, random, sys attempts = 5 #def start is basically the log-on to access the rest of the ATM, if you don't know the pin you're stuck here def start(): print("Hello! Please input your card")    time.sleep(4)    user_try = int(input("Thank you! Please input your pin: ")) if user_try == pin: print("Card info correct") elif user_try != pin: attempts = attempts-1 print("Sorry, That pin wasn't right. you have",attempts,"more attempts") if attempts == 0: print("Sorry you've ran out of attempts to access this account") sys.exit time.sleep(1) if user_try == pin: print("Card info correct") start()      

edit: absolutely butchered this, actual code is in the first reply

【已解决】Python报错:UnboundLocalError:local variable ‘xxx‘ referenced before assignment

python local variable might be referenced before assignment

Python编程实战:深入解析与解决UnboundLocalError的策略

在Python编程过程中,开发者可能会遭遇 UnboundLocalError 这一常见错误,其错误信息通常表现为“local variable ‘xxx’ referenced before assignment”,意味着尝试访问一个在当前作用域内未被事先赋值的局部变量。本文将通过具体场景分析,揭示错误背后的原理,并提供一系列实用解决方案,助你轻松跨越这一编程挑战。

在这里插入图片描述

运行上述代码时,由于在累加成绩前未对 total 进行初始化,程序将抛出 UnboundLocalError 。

  • 确保变量初始化 :在使用任何变量前,务必确保已经赋予了初始值。对于上述案例,应在循环前正确初始化 total 变量。

修正后的代码示例:

明确作用域管理 :如果变量需要在多个作用域内共享,考虑其定义的位置,或使用全局变量(谨慎使用,以免造成不必要的副作用)。

循环和条件语句中的变量处理 :在循环或条件判断中,确保变量在所有可能的执行路径上都得到初始化。

利用默认值 :在函数参数中提供默认值,可以避免因参数未传入而导致的未初始化错误。

UnboundLocalError 的产生,实质上是对Python作用域规则理解和应用上的疏漏。通过上述策略的应用,开发者不仅能够有效避免此类错误,还能进一步加深对Python语言特性的理解。记住,良好的编程习惯,如及时初始化变量、清晰地界定作用域,是编写高质量代码的基石。在编程之旅上,每一步的谨慎与反思,都是通往卓越的必经之路。

祝大家学习顺利~ 如有任何错误,恳请批评指正~~ 以上是我通过各种方式得出的经验和方法,欢迎大家评论区留言讨论呀,如果文章对你们产生了帮助,也欢迎点赞收藏,我会继续努力分享更多干货~

🎈关注我的公众号AI Sun可以获取Chatgpt最新发展报告以及腾讯字节等众多大厂面经。 😎也欢迎大家和我交流,相互学习,提升技术,风里雨里,我在等你~

python local variable might be referenced before assignment

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

python local variable might be referenced before assignment

请填写红包祝福语或标题

python local variable might be referenced before assignment

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

python local variable might be referenced before assignment

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

python local variable might be referenced before assignment

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

python local variable might be referenced before assignment

Navigazione

  • successivo |
  • precedente |
  • Python »
  • 3.14.0a0 Documentation »
  • Extending and Embedding the Python Interpreter »
  • 1. Extending Python with C or C++
  • Theme Auto Light Dark |

1. Extending Python with C or C++ ¶

It is quite easy to add new built-in modules to Python, if you know how to program in C. Such extension modules can do two things that can’t be done directly in Python: they can implement new built-in object types, and they can call C library functions and system calls.

To support extensions, the Python API (Application Programmers Interface) defines a set of functions, macros and variables that provide access to most aspects of the Python run-time system. The Python API is incorporated in a C source file by including the header "Python.h" .

The compilation of an extension module depends on its intended use as well as on your system setup; details are given in later chapters.

The C extension interface is specific to CPython, and extension modules do not work on other Python implementations. In many cases, it is possible to avoid writing C extensions and preserve portability to other implementations. For example, if your use case is calling C library functions or system calls, you should consider using the ctypes module or the cffi library rather than writing custom C code. These modules let you write Python code to interface with C code and are more portable between implementations of Python than writing and compiling a C extension module.

1.1. A Simple Example ¶

Let’s create an extension module called spam (the favorite food of Monty Python fans…) and let’s say we want to create a Python interface to the C library function system() [ 1 ] . This function takes a null-terminated character string as argument and returns an integer. We want this function to be callable from Python as follows:

Begin by creating a file spammodule.c . (Historically, if a module is called spam , the C file containing its implementation is called spammodule.c ; if the module name is very long, like spammify , the module name can be just spammify.c .)

The first two lines of our file can be:

which pulls in the Python API (you can add a comment describing the purpose of the module and a copyright notice if you like).

Since Python may define some pre-processor definitions which affect the standard headers on some systems, you must include Python.h before any standard headers are included.

#define PY_SSIZE_T_CLEAN was used to indicate that Py_ssize_t should be used in some APIs instead of int . It is not necessary since Python 3.13, but we keep it here for backward compatibility. See Strings and buffers for a description of this macro.

All user-visible symbols defined by Python.h have a prefix of Py or PY , except those defined in standard header files. For convenience, and since they are used extensively by the Python interpreter, "Python.h" includes a few standard header files: <stdio.h> , <string.h> , <errno.h> , and <stdlib.h> . If the latter header file does not exist on your system, it declares the functions malloc() , free() and realloc() directly.

The next thing we add to our module file is the C function that will be called when the Python expression spam.system(string) is evaluated (we’ll see shortly how it ends up being called):

There is a straightforward translation from the argument list in Python (for example, the single expression "ls -l" ) to the arguments passed to the C function. The C function always has two arguments, conventionally named self and args .

The self argument points to the module object for module-level functions; for a method it would point to the object instance.

The args argument will be a pointer to a Python tuple object containing the arguments. Each item of the tuple corresponds to an argument in the call’s argument list. The arguments are Python objects — in order to do anything with them in our C function we have to convert them to C values. The function PyArg_ParseTuple() in the Python API checks the argument types and converts them to C values. It uses a template string to determine the required types of the arguments as well as the types of the C variables into which to store the converted values. More about this later.

PyArg_ParseTuple() returns true (nonzero) if all arguments have the right type and its components have been stored in the variables whose addresses are passed. It returns false (zero) if an invalid argument list was passed. In the latter case it also raises an appropriate exception so the calling function can return NULL immediately (as we saw in the example).

1.2. Intermezzo: Errors and Exceptions ¶

An important convention throughout the Python interpreter is the following: when a function fails, it should set an exception condition and return an error value (usually -1 or a NULL pointer). Exception information is stored in three members of the interpreter’s thread state. These are NULL if there is no exception. Otherwise they are the C equivalents of the members of the Python tuple returned by sys.exc_info() . These are the exception type, exception instance, and a traceback object. It is important to know about them to understand how errors are passed around.

The Python API defines a number of functions to set various types of exceptions.

The most common one is PyErr_SetString() . Its arguments are an exception object and a C string. The exception object is usually a predefined object like PyExc_ZeroDivisionError . The C string indicates the cause of the error and is converted to a Python string object and stored as the «associated value» of the exception.

Another useful function is PyErr_SetFromErrno() , which only takes an exception argument and constructs the associated value by inspection of the global variable errno . The most general function is PyErr_SetObject() , which takes two object arguments, the exception and its associated value. You don’t need to Py_INCREF() the objects passed to any of these functions.

You can test non-destructively whether an exception has been set with PyErr_Occurred() . This returns the current exception object, or NULL if no exception has occurred. You normally don’t need to call PyErr_Occurred() to see whether an error occurred in a function call, since you should be able to tell from the return value.

When a function f that calls another function g detects that the latter fails, f should itself return an error value (usually NULL or -1 ). It should not call one of the PyErr_* functions — one has already been called by g . f ’s caller is then supposed to also return an error indication to its caller, again without calling PyErr_* , and so on — the most detailed cause of the error was already reported by the function that first detected it. Once the error reaches the Python interpreter’s main loop, this aborts the currently executing Python code and tries to find an exception handler specified by the Python programmer.

(There are situations where a module can actually give a more detailed error message by calling another PyErr_* function, and in such cases it is fine to do so. As a general rule, however, this is not necessary, and can cause information about the cause of the error to be lost: most operations can fail for a variety of reasons.)

To ignore an exception set by a function call that failed, the exception condition must be cleared explicitly by calling PyErr_Clear() . The only time C code should call PyErr_Clear() is if it doesn’t want to pass the error on to the interpreter but wants to handle it completely by itself (possibly by trying something else, or pretending nothing went wrong).

Every failing malloc() call must be turned into an exception — the direct caller of malloc() (or realloc() ) must call PyErr_NoMemory() and return a failure indicator itself. All the object-creating functions (for example, PyLong_FromLong() ) already do this, so this note is only relevant to those who call malloc() directly.

Also note that, with the important exception of PyArg_ParseTuple() and friends, functions that return an integer status usually return a positive value or zero for success and -1 for failure, like Unix system calls.

Finally, be careful to clean up garbage (by making Py_XDECREF() or Py_DECREF() calls for objects you have already created) when you return an error indicator!

The choice of which exception to raise is entirely yours. There are predeclared C objects corresponding to all built-in Python exceptions, such as PyExc_ZeroDivisionError , which you can use directly. Of course, you should choose exceptions wisely — don’t use PyExc_TypeError to mean that a file couldn’t be opened (that should probably be PyExc_OSError ). If something’s wrong with the argument list, the PyArg_ParseTuple() function usually raises PyExc_TypeError . If you have an argument whose value must be in a particular range or must satisfy other conditions, PyExc_ValueError is appropriate.

You can also define a new exception that is unique to your module. For this, you usually declare a static object variable at the beginning of your file:

and initialize it in your module’s initialization function ( PyInit_spam() ) with an exception object:

Note that the Python name for the exception object is spam.error . The PyErr_NewException() function may create a class with the base class being Exception (unless another class is passed in instead of NULL ), described in Built-in Exceptions .

Note also that the SpamError variable retains a reference to the newly created exception class; this is intentional! Since the exception could be removed from the module by external code, an owned reference to the class is needed to ensure that it will not be discarded, causing SpamError to become a dangling pointer. Should it become a dangling pointer, C code which raises the exception could cause a core dump or other unintended side effects.

We discuss the use of PyMODINIT_FUNC as a function return type later in this sample.

The spam.error exception can be raised in your extension module using a call to PyErr_SetString() as shown below:

1.3. Back to the Example ¶

Going back to our example function, you should now be able to understand this statement:

It returns NULL (the error indicator for functions returning object pointers) if an error is detected in the argument list, relying on the exception set by PyArg_ParseTuple() . Otherwise the string value of the argument has been copied to the local variable command . This is a pointer assignment and you are not supposed to modify the string to which it points (so in Standard C, the variable command should properly be declared as const char *command ).

The next statement is a call to the Unix function system() , passing it the string we just got from PyArg_ParseTuple() :

Our spam.system() function must return the value of sts as a Python object. This is done using the function PyLong_FromLong() .

In this case, it will return an integer object. (Yes, even integers are objects on the heap in Python!)

If you have a C function that returns no useful argument (a function returning void ), the corresponding Python function must return None . You need this idiom to do so (which is implemented by the Py_RETURN_NONE macro):

Py_None is the C name for the special Python object None . It is a genuine Python object rather than a NULL pointer, which means «error» in most contexts, as we have seen.

1.4. The Module’s Method Table and Initialization Function ¶

I promised to show how spam_system() is called from Python programs. First, we need to list its name and address in a «method table»:

Note the third entry ( METH_VARARGS ). This is a flag telling the interpreter the calling convention to be used for the C function. It should normally always be METH_VARARGS or METH_VARARGS | METH_KEYWORDS ; a value of 0 means that an obsolete variant of PyArg_ParseTuple() is used.

When using only METH_VARARGS , the function should expect the Python-level parameters to be passed in as a tuple acceptable for parsing via PyArg_ParseTuple() ; more information on this function is provided below.

The METH_KEYWORDS bit may be set in the third field if keyword arguments should be passed to the function. In this case, the C function should accept a third PyObject * parameter which will be a dictionary of keywords. Use PyArg_ParseTupleAndKeywords() to parse the arguments to such a function.

The method table must be referenced in the module definition structure:

This structure, in turn, must be passed to the interpreter in the module’s initialization function. The initialization function must be named PyInit_name() , where name is the name of the module, and should be the only non- static item defined in the module file:

Note that PyMODINIT_FUNC declares the function as PyObject * return type, declares any special linkage declarations required by the platform, and for C++ declares the function as extern "C" .

When the Python program imports module spam for the first time, PyInit_spam() is called. (See below for comments about embedding Python.) It calls PyModule_Create() , which returns a module object, and inserts built-in function objects into the newly created module based upon the table (an array of PyMethodDef structures) found in the module definition. PyModule_Create() returns a pointer to the module object that it creates. It may abort with a fatal error for certain errors, or return NULL if the module could not be initialized satisfactorily. The init function must return the module object to its caller, so that it then gets inserted into sys.modules .

When embedding Python, the PyInit_spam() function is not called automatically unless there’s an entry in the PyImport_Inittab table. To add the module to the initialization table, use PyImport_AppendInittab() , optionally followed by an import of the module:

Removing entries from sys.modules or importing compiled modules into multiple interpreters within a process (or following a fork() without an intervening exec() ) can create problems for some extension modules. Extension module authors should exercise caution when initializing internal data structures.

A more substantial example module is included in the Python source distribution as Modules/xxmodule.c . This file may be used as a template or simply read as an example.

Unlike our spam example, xxmodule uses multi-phase initialization (new in Python 3.5), where a PyModuleDef structure is returned from PyInit_spam , and creation of the module is left to the import machinery. For details on multi-phase initialization, see PEP 489 .

1.5. Compilation and Linkage ¶

There are two more things to do before you can use your new extension: compiling and linking it with the Python system. If you use dynamic loading, the details may depend on the style of dynamic loading your system uses; see the chapters about building extension modules (chapter Building C and C++ Extensions ) and additional information that pertains only to building on Windows (chapter Building C and C++ Extensions on Windows ) for more information about this.

If you can’t use dynamic loading, or if you want to make your module a permanent part of the Python interpreter, you will have to change the configuration setup and rebuild the interpreter. Luckily, this is very simple on Unix: just place your file ( spammodule.c for example) in the Modules/ directory of an unpacked source distribution, add a line to the file Modules/Setup.local describing your file:

and rebuild the interpreter by running make in the toplevel directory. You can also run make in the Modules/ subdirectory, but then you must first rebuild Makefile there by running “ make Makefile”. (This is necessary each time you change the Setup file.)

If your module requires additional libraries to link with, these can be listed on the line in the configuration file as well, for instance:

1.6. Calling Python Functions from C ¶

So far we have concentrated on making C functions callable from Python. The reverse is also useful: calling Python functions from C. This is especially the case for libraries that support so-called «callback» functions. If a C interface makes use of callbacks, the equivalent Python often needs to provide a callback mechanism to the Python programmer; the implementation will require calling the Python callback functions from a C callback. Other uses are also imaginable.

Fortunately, the Python interpreter is easily called recursively, and there is a standard interface to call a Python function. (I won’t dwell on how to call the Python parser with a particular string as input — if you’re interested, have a look at the implementation of the -c command line option in Modules/main.c from the Python source code.)

Calling a Python function is easy. First, the Python program must somehow pass you the Python function object. You should provide a function (or some other interface) to do this. When this function is called, save a pointer to the Python function object (be careful to Py_INCREF() it!) in a global variable — or wherever you see fit. For example, the following function might be part of a module definition:

This function must be registered with the interpreter using the METH_VARARGS flag; this is described in section The Module’s Method Table and Initialization Function . The PyArg_ParseTuple() function and its arguments are documented in section Extracting Parameters in Extension Functions .

The macros Py_XINCREF() and Py_XDECREF() increment/decrement the reference count of an object and are safe in the presence of NULL pointers (but note that temp will not be NULL in this context). More info on them in section Reference Counts .

Later, when it is time to call the function, you call the C function PyObject_CallObject() . This function has two arguments, both pointers to arbitrary Python objects: the Python function, and the argument list. The argument list must always be a tuple object, whose length is the number of arguments. To call the Python function with no arguments, pass in NULL , or an empty tuple; to call it with one argument, pass a singleton tuple. Py_BuildValue() returns a tuple when its format string consists of zero or more format codes between parentheses. For example:

PyObject_CallObject() returns a Python object pointer: this is the return value of the Python function. PyObject_CallObject() is «reference-count-neutral» with respect to its arguments. In the example a new tuple was created to serve as the argument list, which is Py_DECREF() -ed immediately after the PyObject_CallObject() call.

The return value of PyObject_CallObject() is «new»: either it is a brand new object, or it is an existing object whose reference count has been incremented. So, unless you want to save it in a global variable, you should somehow Py_DECREF() the result, even (especially!) if you are not interested in its value.

Before you do this, however, it is important to check that the return value isn’t NULL . If it is, the Python function terminated by raising an exception. If the C code that called PyObject_CallObject() is called from Python, it should now return an error indication to its Python caller, so the interpreter can print a stack trace, or the calling Python code can handle the exception. If this is not possible or desirable, the exception should be cleared by calling PyErr_Clear() . For example:

Depending on the desired interface to the Python callback function, you may also have to provide an argument list to PyObject_CallObject() . In some cases the argument list is also provided by the Python program, through the same interface that specified the callback function. It can then be saved and used in the same manner as the function object. In other cases, you may have to construct a new tuple to pass as the argument list. The simplest way to do this is to call Py_BuildValue() . For example, if you want to pass an integral event code, you might use the following code:

Note the placement of Py_DECREF(arglist) immediately after the call, before the error check! Also note that strictly speaking this code is not complete: Py_BuildValue() may run out of memory, and this should be checked.

You may also call a function with keyword arguments by using PyObject_Call() , which supports arguments and keyword arguments. As in the above example, we use Py_BuildValue() to construct the dictionary.

1.7. Extracting Parameters in Extension Functions ¶

The PyArg_ParseTuple() function is declared as follows:

The arg argument must be a tuple object containing an argument list passed from Python to a C function. The format argument must be a format string, whose syntax is explained in Parsing arguments and building values in the Python/C API Reference Manual. The remaining arguments must be addresses of variables whose type is determined by the format string.

Note that while PyArg_ParseTuple() checks that the Python arguments have the required types, it cannot check the validity of the addresses of C variables passed to the call: if you make mistakes there, your code will probably crash or at least overwrite random bits in memory. So be careful!

Note that any Python object references which are provided to the caller are borrowed references; do not decrement their reference count!

Some example calls:

1.8. Keyword Parameters for Extension Functions ¶

The PyArg_ParseTupleAndKeywords() function is declared as follows:

The arg and format parameters are identical to those of the PyArg_ParseTuple() function. The kwdict parameter is the dictionary of keywords received as the third parameter from the Python runtime. The kwlist parameter is a NULL -terminated list of strings which identify the parameters; the names are matched with the type information from format from left to right. On success, PyArg_ParseTupleAndKeywords() returns true, otherwise it returns false and raises an appropriate exception.

Nested tuples cannot be parsed when using keyword arguments! Keyword parameters passed in which are not present in the kwlist will cause TypeError to be raised.

Here is an example module which uses keywords, based on an example by Geoff Philbrick ( philbrick @ hks . com ):

1.9. Building Arbitrary Values ¶

This function is the counterpart to PyArg_ParseTuple() . It is declared as follows:

It recognizes a set of format units similar to the ones recognized by PyArg_ParseTuple() , but the arguments (which are input to the function, not output) must not be pointers, just values. It returns a new Python object, suitable for returning from a C function called from Python.

One difference with PyArg_ParseTuple() : while the latter requires its first argument to be a tuple (since Python argument lists are always represented as tuples internally), Py_BuildValue() does not always build a tuple. It builds a tuple only if its format string contains two or more format units. If the format string is empty, it returns None ; if it contains exactly one format unit, it returns whatever object is described by that format unit. To force it to return a tuple of size 0 or one, parenthesize the format string.

Examples (to the left the call, to the right the resulting Python value):

1.10. Reference Counts ¶

In languages like C or C++, the programmer is responsible for dynamic allocation and deallocation of memory on the heap. In C, this is done using the functions malloc() and free() . In C++, the operators new and delete are used with essentially the same meaning and we’ll restrict the following discussion to the C case.

Every block of memory allocated with malloc() should eventually be returned to the pool of available memory by exactly one call to free() . It is important to call free() at the right time. If a block’s address is forgotten but free() is not called for it, the memory it occupies cannot be reused until the program terminates. This is called a memory leak . On the other hand, if a program calls free() for a block and then continues to use the block, it creates a conflict with reuse of the block through another malloc() call. This is called using freed memory . It has the same bad consequences as referencing uninitialized data — core dumps, wrong results, mysterious crashes.

Common causes of memory leaks are unusual paths through the code. For instance, a function may allocate a block of memory, do some calculation, and then free the block again. Now a change in the requirements for the function may add a test to the calculation that detects an error condition and can return prematurely from the function. It’s easy to forget to free the allocated memory block when taking this premature exit, especially when it is added later to the code. Such leaks, once introduced, often go undetected for a long time: the error exit is taken only in a small fraction of all calls, and most modern machines have plenty of virtual memory, so the leak only becomes apparent in a long-running process that uses the leaking function frequently. Therefore, it’s important to prevent leaks from happening by having a coding convention or strategy that minimizes this kind of errors.

Since Python makes heavy use of malloc() and free() , it needs a strategy to avoid memory leaks as well as the use of freed memory. The chosen method is called reference counting . The principle is simple: every object contains a counter, which is incremented when a reference to the object is stored somewhere, and which is decremented when a reference to it is deleted. When the counter reaches zero, the last reference to the object has been deleted and the object is freed.

An alternative strategy is called automatic garbage collection . (Sometimes, reference counting is also referred to as a garbage collection strategy, hence my use of «automatic» to distinguish the two.) The big advantage of automatic garbage collection is that the user doesn’t need to call free() explicitly. (Another claimed advantage is an improvement in speed or memory usage — this is no hard fact however.) The disadvantage is that for C, there is no truly portable automatic garbage collector, while reference counting can be implemented portably (as long as the functions malloc() and free() are available — which the C Standard guarantees). Maybe some day a sufficiently portable automatic garbage collector will be available for C. Until then, we’ll have to live with reference counts.

While Python uses the traditional reference counting implementation, it also offers a cycle detector that works to detect reference cycles. This allows applications to not worry about creating direct or indirect circular references; these are the weakness of garbage collection implemented using only reference counting. Reference cycles consist of objects which contain (possibly indirect) references to themselves, so that each object in the cycle has a reference count which is non-zero. Typical reference counting implementations are not able to reclaim the memory belonging to any objects in a reference cycle, or referenced from the objects in the cycle, even though there are no further references to the cycle itself.

The cycle detector is able to detect garbage cycles and can reclaim them. The gc module exposes a way to run the detector (the collect() function), as well as configuration interfaces and the ability to disable the detector at runtime.

1.10.1. Reference Counting in Python ¶

There are two macros, Py_INCREF(x) and Py_DECREF(x) , which handle the incrementing and decrementing of the reference count. Py_DECREF() also frees the object when the count reaches zero. For flexibility, it doesn’t call free() directly — rather, it makes a call through a function pointer in the object’s type object . For this purpose (and others), every object also contains a pointer to its type object.

The big question now remains: when to use Py_INCREF(x) and Py_DECREF(x) ? Let’s first introduce some terms. Nobody «owns» an object; however, you can own a reference to an object. An object’s reference count is now defined as the number of owned references to it. The owner of a reference is responsible for calling Py_DECREF() when the reference is no longer needed. Ownership of a reference can be transferred. There are three ways to dispose of an owned reference: pass it on, store it, or call Py_DECREF() . Forgetting to dispose of an owned reference creates a memory leak.

It is also possible to borrow [ 2 ] a reference to an object. The borrower of a reference should not call Py_DECREF() . The borrower must not hold on to the object longer than the owner from which it was borrowed. Using a borrowed reference after the owner has disposed of it risks using freed memory and should be avoided completely [ 3 ] .

The advantage of borrowing over owning a reference is that you don’t need to take care of disposing of the reference on all possible paths through the code — in other words, with a borrowed reference you don’t run the risk of leaking when a premature exit is taken. The disadvantage of borrowing over owning is that there are some subtle situations where in seemingly correct code a borrowed reference can be used after the owner from which it was borrowed has in fact disposed of it.

A borrowed reference can be changed into an owned reference by calling Py_INCREF() . This does not affect the status of the owner from which the reference was borrowed — it creates a new owned reference, and gives full owner responsibilities (the new owner must dispose of the reference properly, as well as the previous owner).

1.10.2. Ownership Rules ¶

Whenever an object reference is passed into or out of a function, it is part of the function’s interface specification whether ownership is transferred with the reference or not.

Most functions that return a reference to an object pass on ownership with the reference. In particular, all functions whose function it is to create a new object, such as PyLong_FromLong() and Py_BuildValue() , pass ownership to the receiver. Even if the object is not actually new, you still receive ownership of a new reference to that object. For instance, PyLong_FromLong() maintains a cache of popular values and can return a reference to a cached item.

Many functions that extract objects from other objects also transfer ownership with the reference, for instance PyObject_GetAttrString() . The picture is less clear, here, however, since a few common routines are exceptions: PyTuple_GetItem() , PyList_GetItem() , PyDict_GetItem() , and PyDict_GetItemString() all return references that you borrow from the tuple, list or dictionary.

The function PyImport_AddModule() also returns a borrowed reference, even though it may actually create the object it returns: this is possible because an owned reference to the object is stored in sys.modules .

When you pass an object reference into another function, in general, the function borrows the reference from you — if it needs to store it, it will use Py_INCREF() to become an independent owner. There are exactly two important exceptions to this rule: PyTuple_SetItem() and PyList_SetItem() . These functions take over ownership of the item passed to them — even if they fail! (Note that PyDict_SetItem() and friends don’t take over ownership — they are «normal.»)

When a C function is called from Python, it borrows references to its arguments from the caller. The caller owns a reference to the object, so the borrowed reference’s lifetime is guaranteed until the function returns. Only when such a borrowed reference must be stored or passed on, it must be turned into an owned reference by calling Py_INCREF() .

The object reference returned from a C function that is called from Python must be an owned reference — ownership is transferred from the function to its caller.

1.10.3. Thin Ice ¶

There are a few situations where seemingly harmless use of a borrowed reference can lead to problems. These all have to do with implicit invocations of the interpreter, which can cause the owner of a reference to dispose of it.

The first and most important case to know about is using Py_DECREF() on an unrelated object while borrowing a reference to a list item. For instance:

This function first borrows a reference to list[0] , then replaces list[1] with the value 0 , and finally prints the borrowed reference. Looks harmless, right? But it’s not!

Let’s follow the control flow into PyList_SetItem() . The list owns references to all its items, so when item 1 is replaced, it has to dispose of the original item 1. Now let’s suppose the original item 1 was an instance of a user-defined class, and let’s further suppose that the class defined a __del__() method. If this class instance has a reference count of 1, disposing of it will call its __del__() method.

Since it is written in Python, the __del__() method can execute arbitrary Python code. Could it perhaps do something to invalidate the reference to item in bug() ? You bet! Assuming that the list passed into bug() is accessible to the __del__() method, it could execute a statement to the effect of del list[0] , and assuming this was the last reference to that object, it would free the memory associated with it, thereby invalidating item .

The solution, once you know the source of the problem, is easy: temporarily increment the reference count. The correct version of the function reads:

This is a true story. An older version of Python contained variants of this bug and someone spent a considerable amount of time in a C debugger to figure out why his __del__() methods would fail…

The second case of problems with a borrowed reference is a variant involving threads. Normally, multiple threads in the Python interpreter can’t get in each other’s way, because there is a global lock protecting Python’s entire object space. However, it is possible to temporarily release this lock using the macro Py_BEGIN_ALLOW_THREADS , and to re-acquire it using Py_END_ALLOW_THREADS . This is common around blocking I/O calls, to let other threads use the processor while waiting for the I/O to complete. Obviously, the following function has the same problem as the previous one:

1.10.4. NULL Pointers ¶

In general, functions that take object references as arguments do not expect you to pass them NULL pointers, and will dump core (or cause later core dumps) if you do so. Functions that return object references generally return NULL only to indicate that an exception occurred. The reason for not testing for NULL arguments is that functions often pass the objects they receive on to other function — if each function were to test for NULL , there would be a lot of redundant tests and the code would run more slowly.

It is better to test for NULL only at the «source:» when a pointer that may be NULL is received, for example, from malloc() or from a function that may raise an exception.

The macros Py_INCREF() and Py_DECREF() do not check for NULL pointers — however, their variants Py_XINCREF() and Py_XDECREF() do.

The macros for checking for a particular object type ( Pytype_Check() ) don’t check for NULL pointers — again, there is much code that calls several of these in a row to test an object against various different expected types, and this would generate redundant tests. There are no variants with NULL checking.

The C function calling mechanism guarantees that the argument list passed to C functions ( args in the examples) is never NULL — in fact it guarantees that it is always a tuple [ 4 ] .

It is a severe error to ever let a NULL pointer «escape» to the Python user.

1.11. Writing Extensions in C++ ¶

It is possible to write extension modules in C++. Some restrictions apply. If the main program (the Python interpreter) is compiled and linked by the C compiler, global or static objects with constructors cannot be used. This is not a problem if the main program is linked by the C++ compiler. Functions that will be called by the Python interpreter (in particular, module initialization functions) have to be declared using extern "C" . It is unnecessary to enclose the Python header files in extern "C" {...} — they use this form already if the symbol __cplusplus is defined (all recent C++ compilers define this symbol).

1.12. Providing a C API for an Extension Module ¶

Many extension modules just provide new functions and types to be used from Python, but sometimes the code in an extension module can be useful for other extension modules. For example, an extension module could implement a type «collection» which works like lists without order. Just like the standard Python list type has a C API which permits extension modules to create and manipulate lists, this new collection type should have a set of C functions for direct manipulation from other extension modules.

At first sight this seems easy: just write the functions (without declaring them static , of course), provide an appropriate header file, and document the C API. And in fact this would work if all extension modules were always linked statically with the Python interpreter. When modules are used as shared libraries, however, the symbols defined in one module may not be visible to another module. The details of visibility depend on the operating system; some systems use one global namespace for the Python interpreter and all extension modules (Windows, for example), whereas others require an explicit list of imported symbols at module link time (AIX is one example), or offer a choice of different strategies (most Unices). And even if symbols are globally visible, the module whose functions one wishes to call might not have been loaded yet!

Portability therefore requires not to make any assumptions about symbol visibility. This means that all symbols in extension modules should be declared static , except for the module’s initialization function, in order to avoid name clashes with other extension modules (as discussed in section The Module’s Method Table and Initialization Function ). And it means that symbols that should be accessible from other extension modules must be exported in a different way.

Python provides a special mechanism to pass C-level information (pointers) from one extension module to another one: Capsules. A Capsule is a Python data type which stores a pointer ( void * ). Capsules can only be created and accessed via their C API, but they can be passed around like any other Python object. In particular, they can be assigned to a name in an extension module’s namespace. Other extension modules can then import this module, retrieve the value of this name, and then retrieve the pointer from the Capsule.

There are many ways in which Capsules can be used to export the C API of an extension module. Each function could get its own Capsule, or all C API pointers could be stored in an array whose address is published in a Capsule. And the various tasks of storing and retrieving the pointers can be distributed in different ways between the module providing the code and the client modules.

Whichever method you choose, it’s important to name your Capsules properly. The function PyCapsule_New() takes a name parameter ( const char * ); you’re permitted to pass in a NULL name, but we strongly encourage you to specify a name. Properly named Capsules provide a degree of runtime type-safety; there is no feasible way to tell one unnamed Capsule from another.

In particular, Capsules used to expose C APIs should be given a name following this convention:

The convenience function PyCapsule_Import() makes it easy to load a C API provided via a Capsule, but only if the Capsule’s name matches this convention. This behavior gives C API users a high degree of certainty that the Capsule they load contains the correct C API.

The following example demonstrates an approach that puts most of the burden on the writer of the exporting module, which is appropriate for commonly used library modules. It stores all C API pointers (just one in the example!) in an array of void pointers which becomes the value of a Capsule. The header file corresponding to the module provides a macro that takes care of importing the module and retrieving its C API pointers; client modules only have to call this macro before accessing the C API.

The exporting module is a modification of the spam module from section A Simple Example . The function spam.system() does not call the C library function system() directly, but a function PySpam_System() , which would of course do something more complicated in reality (such as adding «spam» to every command). This function PySpam_System() is also exported to other extension modules.

The function PySpam_System() is a plain C function, declared static like everything else:

The function spam_system() is modified in a trivial way:

In the beginning of the module, right after the line

two more lines must be added:

The #define is used to tell the header file that it is being included in the exporting module, not a client module. Finally, the module’s initialization function must take care of initializing the C API pointer array:

Note that PySpam_API is declared static ; otherwise the pointer array would disappear when PyInit_spam() terminates!

The bulk of the work is in the header file spammodule.h , which looks like this:

All that a client module must do in order to have access to the function PySpam_System() is to call the function (or rather macro) import_spam() in its initialization function:

The main disadvantage of this approach is that the file spammodule.h is rather complicated. However, the basic structure is the same for each function that is exported, so it has to be learned only once.

Finally it should be mentioned that Capsules offer additional functionality, which is especially useful for memory allocation and deallocation of the pointer stored in a Capsule. The details are described in the Python/C API Reference Manual in the section Capsules and in the implementation of Capsules (files Include/pycapsule.h and Objects/pycapsule.c in the Python source code distribution).

Table of Contents

  • 1.1. A Simple Example
  • 1.2. Intermezzo: Errors and Exceptions
  • 1.3. Back to the Example
  • 1.4. The Module’s Method Table and Initialization Function
  • 1.5. Compilation and Linkage
  • 1.6. Calling Python Functions from C
  • 1.7. Extracting Parameters in Extension Functions
  • 1.8. Keyword Parameters for Extension Functions
  • 1.9. Building Arbitrary Values
  • 1.10.1. Reference Counting in Python
  • 1.10.2. Ownership Rules
  • 1.10.3. Thin Ice
  • 1.10.4. NULL Pointers
  • 1.11. Writing Extensions in C++
  • 1.12. Providing a C API for an Extension Module

Argomento precedente

Extending and Embedding the Python Interpreter

Argomento successivo

2. Defining Extension Types: Tutorial

Questa pagina

  • Riporta un Bug
  • Visualizza codice
  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Seaborn Error: local variable 'boxprops' referenced before assignment [closed]

I am trying to plot using seaborn boxplot, however, I get the following error:

These codes were executing fine last week. I have tried updating seaborn and pyfolio, yet I still get the same error. Does anyone know how to fix this?

**Attempted Solutions: **

  • Updating seaborn and pyfolio to the latest versions.

Does anyone have suggestions on how to resolve this issue?

JohanC's user avatar

  • Can you test the code as shown? Does it still generate the error? Do you get other warnings? –  JohanC Commented Jun 24 at 13:58
  • @JohanC It works ! thank you! Do you know what the exact problem was? –  Rhea Groenenberg Commented Jun 24 at 14:05
  • I think there was something wrong with the input data. Maybe the problem is "solved" in this test, but not with your real data. In that case, you could try to print out information about filtered_df and create test data similar to that one. Or maybe your update of pyfolio finally had effect (I suppose pyfolio changed something to the input they are sending to seaborn). –  JohanC Commented Jun 24 at 14:10
  • I'm voting to close this issue as not reproducible. –  Trenton McKinney Commented Jun 25 at 1:05

Browse other questions tagged python matplotlib seaborn pyfolio or ask your own question .

  • Featured on Meta
  • Upcoming sign-up experiments related to tags
  • Policy: Generative AI (e.g., ChatGPT) is banned
  • The [lib] tag is being burninated
  • What makes a homepage useful for logged-in users

Hot Network Questions

  • How to fix misaligned objects that look fine in viewport but not in render?
  • Can my IP be found on Telegram by malicious people?
  • Font shape warnings in LuaLaTeX but not XeLaTeX
  • Simple Container Class
  • How do you say "living being" in Classical Latin?
  • Do capacitor packages make a difference in MLCCs?
  • What to do if you disagree with a juror during master's thesis defense?
  • Is it possible to complete a Phd on your own?
  • Less ridiculous way to prove that an Ascii character compares equal with itself in Coq
  • Were there engineers in airship nacelles, and why were they there?
  • Rear shifter cable wont stay in anything but the highest gear
  • Why don't cars use LiFePO4 batteries as they seem to be equivalent in price to AGM?
  • Where can I access records of the 1947 Superman copyright trial?
  • ModSecurity rules that block user-agents - Hosting provider warn me not to remove this rule
  • What does ‘a grade-hog’ mean?
  • Is the zero vector necessary to do quantum mechanics?
  • Is automorphism on a compact group necessarily homeomorphism? How about N-dimensional torus?
  • What actual purpose do accent characters in ISO-8859-1 and Windows 1252 serve?
  • Matryoshka doll problem
  • À + infinitive at start of sentence
  • Why depreciation is considered a cost to own a car?
  • How to Draw Gabriel's Horn
  • How would I say the exclamation "What a [blank]" in Latin?
  • Is there any other reason to stockpile minerals aside preparing for war?

python local variable might be referenced before assignment

IMAGES

  1. [SOLVED] Local Variable Referenced Before Assignment

    python local variable might be referenced before assignment

  2. Local variable referenced before assignment Python

    python local variable might be referenced before assignment

  3. Local variable referenced before assignment in Python

    python local variable might be referenced before assignment

  4. python

    python local variable might be referenced before assignment

  5. [SOLVED] Local Variable Referenced Before Assignment

    python local variable might be referenced before assignment

  6. UnboundLocalError: local variable referenced before assignment

    python local variable might be referenced before assignment

VIDEO

  1. Local Variables VS Global Variable

  2. TOPIC- LOCAL & GLOBAL VARIABLE IN PYTHON

  3. Local and Global Variables in Python (Python Tutorial

  4. Python Local Global Variable in Fx lecture54

  5. Master Python Variables for Data Analysts in 2024 #shorts #short #ytshorts #viralshorts #viralshort

  6. Variables in Python #Shorts

COMMENTS

  1. Fix "local variable referenced before assignment" in Python

    Reliable monitoring for your app, databases, infrastructure, and the vendors they rely on. Ping Bot is a powerful uptime and performance monitoring tool that helps notify you and resolve issues before they affect your customers.

  2. 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():

  3. 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

  4. How to Fix Local Variable Referenced Before Assignment Error in Python

    value = value + 1 print (value) increment() If you run this code, you'll get. BASH. UnboundLocalError: local variable 'value' referenced before assignment. The issue is that in this line: PYTHON. value = value + 1. We are defining a local variable called value and then trying to use it before it has been assigned a value, instead of using the ...

  5. 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.

  6. [SOLVED] Local Variable Referenced Before Assignment

    May 4, 2023 April 13, 2022. 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. ... DJANGO - Local Variable Referenced Before Assignment [Form]

  7. 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.

  8. 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 ...

  9. Local variable referenced before assignment in Python

    Using nonlocal keyword. The nonlocal keyword is used to work with variables inside nested functions, where the variable should not belong to the inner function. It allows you to modify the value of a non-local variable in the outer scope. For example, if you have a function outer that defines a variable x, and another function inner inside outer that tries to change the value of x, you need to ...

  10. Local Variable Referenced Before Assignment in Python

    This tutorial explains the reason and solution of the python error local variable referenced before assignment

  11. 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.

  12. Local variable might be referenced before assignment

    local variable 'encrypted' might be referenced before assignment . is a warning generated by the linter. This is because the linter sees that encrypted is assigned values inside two if conditions. if question.lower() == 'yes' or question.lower() == 'y':

  13. 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.

  14. 4 Ways to Fix Local Variable Referenced Before Assignment Error in Python

    Resolving the Local Variable Referenced Before Assignment Error in Python. Python is one of the world's most popular programming languages due to its simplicity ...

  15. 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()

  16. Local variable referenced before assignment: The UnboundLocalError

    Trying to assign a value to a variable that does not have local scope can result in this error: 1 UnboundLocalError: local variable referenced before assignment. Python has a simple rule to determine the scope of a variable. To clarify, a variable is assigned in a function, that variable is local.

  17. Local variable referenced before assignment in Python

    The "Local variable referenced before assignment" appears in Python due to assigning a value to a variable that does not have a local scope. To fix this error, the global keyword, return statement, and nonlocal nested function is used in Python script.

  18. Local variable referenced before assignment in Python

    Use global statement to handle that: def three_upper(s): #check for 3 upper letter. global count. for i in s: From docs: All variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the global symbol table, and then in the table of built-in names.

  19. Local variable referenced before assignment? : r/learnpython

    The issue is caused by this line attempts -= 1. In python there is a concept called scope, which is how it reads variables. By default it uses local scope, so it checks what variables are created within the function to see which are local, if it is not created in the function then it looks outside.

  20. 【已解决】Python报错:UnboundLocalError:local variable 'xxx' referenced before

    Python编程实战:深入解析与解决UnboundLocalError的策略. 在Python编程过程中,开发者可能会遭遇UnboundLocalError这一常见错误,其错误信息通常表现为"local variable 'xxx' referenced before assignment",意味着尝试访问一个在当前作用域内未被事先赋值的局部变量。本文将通过具体场景分析,揭示错误背后的 ...

  21. Python Error, Local variable might be referenced before assignment

    I have to access and print the variable that is local within if function and if I am trying to access it, it shows local variable might be referenced . here is the full code. ... UnBoundLocalError: local variable referenced before assignment (Python) 0. Local variable referenced before assignment. Can you assign global var in a function?

  22. 1. Extending Python with C or C++

    1. Extending Python with C or C++¶. It is quite easy to add new built-in modules to Python, if you know how to program in C. Such extension modules can do two things that can't be done directly in Python: they can implement new built-in object types, and they can call C library functions and system calls.. To support extensions, the Python API (Application Programmers Interface) defines a ...

  23. python

    1. The variables wins, money and losses were declared outside the scope of the fiftyfifty() function, so you cannot update them from inside the function unless you explicitly declare them as global variables like this: def fiftyfifty(bet): global wins, money, losses. chance = random.randint(0,100)

  24. python

    I think there was something wrong with the input data. Maybe the problem is "solved" in this test, but not with your real data. In that case, you could try to print out information about filtered_df and create test data similar to that one. Or maybe your update of pyfolio finally had effect (I suppose pyfolio changed something to the input they are sending to seaborn).