0

Let's say we have a function foo()

def foo():
  foo.a = 2

foo.a = 1
foo()

>> foo.a
>> 2

Is this pythonic or should I wrap the variable in mutable objects such as a list?

Eg:

a = [1]

def foo(a):
  a[0] = 2
foo()

>> a

>> 2
7
  • 1
    What is your goal? Do you want to mutate an object in the calling scope? In global scope? Something else? Commented Oct 18, 2016 at 14:25
  • I want to mutate the variable so that the changes are effected in global scope as well. Also, I don't quite understand what function_name.a(Eg 1) means and why does it simulate mutable object? Commented Oct 18, 2016 at 14:27
  • Also check this: stackoverflow.com/questions/39975659/… Commented Oct 18, 2016 at 14:37
  • 1
    If you use python 3 and are not required to support 2.x, your first example is perfectly pythonic: Bind attributes to the resources they belong to. Commented Oct 18, 2016 at 14:41
  • 1
    @brunodesthuilliers As we don't know the purpose, we cannot tell whether or not this is a do or a don't -- but binding attributes to their respective scopes is way better (and more pythonic) than dealing with data structures in global scope (or even global keywords). Commented Oct 18, 2016 at 15:24

2 Answers 2

1

Since you "want to mutate the variable so that the changes are effected in global scope as well" use the global keyword to tell your function that the name a is a global variable. This means that any assignment to a inside of your function affects the global scope. Without the global declaration assignment to a in your function would create a new local variable.

>>> a = 0
>>> def foo():
...     global a
...     a = 1
...
>>> foo()
>>> a
1
Sign up to request clarification or add additional context in comments.

4 Comments

Can you also explain what foo.a means where foo is a function name. How does the example 1 (as mentioned in the question) work like a mutable variable?
@yask: Python functions are callable objects. Since they are objects you can add attributes using dot notation (such as foo.a = 2). This is a legal but not common practice (but not totally uncommon). If you need to pair behavior with state what you want is to declare a class.
@StevenRumbalski a is no attribute in your example, this may be misleading.
@jbndlr: I'm addressing yask's goal as stated in his comment to the question.
0

Use a class (maybe a bit overkill):

class Foo:
    def __init__(self):
        self.a = 0

def bar(f):
    f.a = 2

foo = Foo()
foo.a = 1
bar(foo)
print(foo.a)

1 Comment

I assume you meant self.a = 0 in Foo.__init__ ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.