`final` keyword equivalent for variables in Python?

后端 未结 11 1945
忘了有多久
忘了有多久 2021-01-30 20:17

I couldn\'t find documentation on an equivalent of Java\'s final in Python, is there such a thing?

I\'m creating a snapshot of an object (used for restorati

相关标签:
11条回答
  • 2021-01-30 20:24

    Having a variable in Java be final basically means that once you assign to a variable, you may not reassign that variable to point to another object. It actually doesn't mean that the object can't be modified. For example, the following Java code works perfectly well:

    public final List<String> messages = new LinkedList<String>();
    
    public void addMessage()
    {
        messages.add("Hello World!");  // this mutates the messages list
    }
    

    but the following wouldn't even compile:

    public final List<String> messages = new LinkedList<String>();
    
    public void changeMessages()
    {
        messages = new ArrayList<String>();  // can't change a final variable
    }
    

    So your question is about whether final exists in Python. It does not.

    However, Python does have immutable data structures. For example, while you can mutate a list, you can't mutate a tuple. You can mutate a set but not a frozenset, etc.

    My advice would be to just not worry about enforcing non-mutation at the language level and simply concentrate on making sure that you don't write any code which mutates these objects after they're assigned.

    0 讨论(0)
  • 2021-01-30 20:26

    There is no such thing. In general, the Python attitude is "if you don't want this modified, just don't modify it". Clients of an API are unlikely to just poke around your undocumented internals anyway.

    You could, I suppose, work around this by using tuples or namedtuples for the relevant bits of your model, which are inherently immutable. That still doesn't help with any part of your model that has to be mutable of course.

    0 讨论(0)
  • 2021-01-30 20:29

    An assign-once variable is a design issue. You design your application in a way that the variable is set once and once only.

    However, if you want run-time checking of your design, you can do it with a wrapper around the object.

    class OnePingOnlyPleaseVassily(object):
        def __init__(self):
            self.value = None
        def set(self, value):
            if self.value is not None:
                raise Exception("Already set.")
            self.value = value
    
    someStateMemo = OnePingOnlyPleaseVassily()
    someStateMemo.set(aValue) # works
    someStateMemo.set(aValue) # fails
    

    That's clunky, but it will detect design problems at run time.

    0 讨论(0)
  • 2021-01-30 20:33

    There is no final equivalent in Python. 

    But, to create read-only fields of class instances, you can use the property function.

    Edit: perhaps you want something like this:

    class WriteOnceReadWhenever:
        def __setattr__(self, attr, value):
            if hasattr(self, attr):
                raise Exception("Attempting to alter read-only value")
    
            self.__dict__[attr] = value
    
    0 讨论(0)
  • 2021-01-30 20:39

    http://code.activestate.com/recipes/576527/ defines a freeze function, although it doesn't work perfectly.

    I would consider just leaving it mutable though.

    0 讨论(0)
  • 2021-01-30 20:45

    Although this is an old question, I figured I would add yet another potential option: You can also use assert to verify a variable is set to what you originally intended it to be set to – a double checking if you will. Although this is not the same as final in Java, it can be used to create a similar effect:

    PI = 3.14
    radius = 3
    
    try:
        assert PI == 3.14
        print PI * radius**2
    except AssertionError:
        print "Yikes."
    

    As seen above, if PI were for some reason not set to 3.14, an AssertionError would be thrown, so a try/except block would probably be a wise addition. Regardless, it may come in handy depending on your situation.

    0 讨论(0)
提交回复
热议问题