0

Assuming:

def myfunc(x):
    my_list  = []
    list.append(x)

is there a keyword to stop a variable(my_list) from being reassigned? Let's suppose that NA is the keyword:

def myfunc(x):
    NA listv  = []
    list.append(x)

in such way that the line will be read and not reassigned but the variable still active appending new values for every function call. I know about the GLOBAL variable, but I just want to know is the keyword exists!

boardrider
  • 5,882
  • 7
  • 49
  • 86
metazord
  • 27
  • 4
  • If you want to *append* a new value, `append` it, and if you want a variable that maintains its value across function invocations, don't make it local to that function. – user2357112 Jun 04 '17 at 00:49
  • You're not appending to the list here – OneCricketeer Jun 04 '17 at 00:49
  • Possible duplicate of [Use of "global" keyword in Python](https://stackoverflow.com/questions/4693120/use-of-global-keyword-in-python) – OneCricketeer Jun 04 '17 at 00:50
  • @cricket_007: While that is one solution to the problem, it is not the only one. I'd say closing this as a duplicate of that is restrictive. – zondo Jun 04 '17 at 00:55
  • @zondo Sure, but it's the keyword that is probably being asked about – OneCricketeer Jun 04 '17 at 00:59
  • so there is no keyword?? – metazord Jun 04 '17 at 01:13
  • Your question is totally unclear. What exactly is the behavior you seek? – juanpa.arrivillaga Jun 04 '17 at 01:27
  • I guess you want to mimick the behavior of static variables inside functions like in C/C++, assignment done only once and skipped afterward: https://stackoverflow.com/a/279586/7983255 As such there is no keyword, only "ways around" I guess. – WKnight02 Jun 04 '17 at 01:37
  • This approach also avoids calls to global variables, and ensures that the function's "local" (inner?) variable is initialized once. – WKnight02 Jun 04 '17 at 01:45

4 Answers4

0

You can declare the variable globally as in C/C++ and use global keyword in python to refer them as variable in global data section. Some of references about them:

Sreyas
  • 461
  • 3
  • 15
0

I guess you are looking for something equivalent to the final keyword in Java. Simply put, there is no such keyword. The Python attitude is "if you don't want this modified at all, just don't modify it, I wont stop you though".

However you can mimic something like it by some tweaks in your class.

class MyFinalVariablesClass:
    def __setattr__(self, attr, value):
        # if it already has this attribute, complain !
        if hasattr(self, attr):
            raise Exception("Attempting to alter read-only value")

        self.__dict__[attr] = value

Or in the case of your variable (haven't tested it)

class WriteOnceReadWhenever:
    def __setattr__(self, attr, value):
        if attr == 'my_list' and hasattr(self, attr):
            raise Exception("Attempting to alter read-only value")
        self.__dict__[attr] = value
Saif Asif
  • 5,516
  • 3
  • 31
  • 48
0

I believe the behaviour you're seeking is almost exactly how mutable default arguments work in python: instantiated only during function definition.

def myfunc(x,*args,my_list=[]):
    my_list.append(x)

The *args will protect the list from being overwritten by an erroneously passed second argument.

0

There is not a keyword to do this. There are workarounds (such as the mutable default argument), but there are better ways to achieve the same thing.

For exaple you could set the variable as a function attribute:

def my_func():
    my_func.my_list.append(1)

my_func.my_list = []

However this is just a hacky way of doing this:

class MyFuncFactory:
    def __init__(self):
        self.my_list = []
    def __call__(self):
        self.my_list.append(1)

Hence you are probably better of writing a class instead of a function in this case.


Sometimes you could use a nonlocal variable. For example to define a key function which requires state I usually write something like:

def my_key_builder():
    some_state = 0

    def key_function(arg):
        nonlocal some_state
        some_state += 1
        return some_state % 2
    return key_function

for x in sorted(a_list, key=my_key_builder()):
    print(x)

Using a nonlocal instead of a global (or mutable default argument) allows you to use the key function multiple times. However if the function becomes slightly bigger using a class is probably the best option.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231