1

I have a function in python and I want to declare 2 variables only the first time I call this function and then change their values, something like this :

def function():
  x=0
  z=2
  if(x>z):
    other_function()
  else:
    x+=1

With this way,every time I call the function(), x becomes 0 and z becomes 2.

I tried to make them global outside of the function() but it gives me error :

UnboundLocalError: local variable 'x' referenced before assignment

How can I declare the values the first time I call the function()?

SaidbakR
  • 13,303
  • 20
  • 101
  • 195
adrian
  • 59
  • 1
  • 4

7 Answers7

2

I disagree with the other answers, that only try to give a direct answer to your question.

You have a combination of state (the variables) with a function / functions using that state. That's what a class is for.

class myclass:
    def __init__(self):
        self.x = 0
        self.z = 2

    def myfunction(self):
        if self.x > self.z:
            other_function()  # Possibly self.other_function()
                              # if that one also uses x or z
        else:
            self.x += 1

Use as:

instance = myclass()
instance.myfunction()
instance.myfunction()  # Etc
RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79
1

You can make use of lexical scope and global in Python:

x = 0
z = 2
def foo():
    global x
    if (x > z):
        bar()
    else:
        x += 1
foo()
Rafał Łużyński
  • 7,083
  • 5
  • 26
  • 38
1

Welcome to closure

You should write some like this:

 
def f(x):
    def g(y):
        return x + y
    return g

def h(x): return lambda y: x + y

a = f(1) b = h(1) f(1)(5) h(1)(5)

mrvol
  • 2,575
  • 18
  • 21
0

If you want to get x and z from somewhere outside of the function then they'll have to be passed to function as arguments. For example:

def function(a,b):
    if(a>b):
        other_function()
    else:
        a+=1

    return a, b

which can then be called with

x, z = function(0,2)
MarkHarley
  • 116
  • 7
0

You could use default function arguments

i.e.)

def function(x = None, z = None):
   if x is None:
        x=0
   if z is None:
        z=2

If you pass the value of x or z the passed value is used else it is initialized to the value given in the function

The6thSense
  • 8,103
  • 8
  • 31
  • 65
0

You can abuse the mighty mutable default value with caution.

def func(vals = {'x': 0, 'z': 2}):
    print vals['x']
    vals['x'] += 1

func()
>> 0
func()
>> 1
func()
>> 2

Although I guess the proper way of doing this will be using a decorator:

def default_value_decorator(func):
    def inner(*args, **kwargs):
        returned_val = func(*args, **kwargs)
        inner.x += 1
        return returned_val
    inner.x = 0
    inner.z = 2
    return inner

@default_value_decorator
def func():
    print func.x

func()
>> 0
func()
>> 1

And a more reusable version where the starting values of x and z can be passed to the decorator:

def default_value_decorator(x, z):
    def a(func):
        def inner(*args, **kwargs):
            returned_val = func(*args, **kwargs)
            inner.x += 1
            return returned_val
        inner.x = x
        inner.z = z
        return inner
    return a

@default_value_decorator(0, 2)
def func():
    print func.x

func()
>> 0
func()
>> 1
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
0

I would put them in a dictionary for better readability:

_VALS = {'x': 0, 'z': 2}
def function():
  if _VALS['x'] > _VALS['z']:
    other_function()
  else:
     _VALS['x'] += 1
Emile
  • 2,946
  • 2
  • 19
  • 22