What's the pythonic way to use getters and setters?

后端 未结 8 2405
盖世英雄少女心
盖世英雄少女心 2020-11-21 23:05

I\'m doing it like:

def set_property(property,value):  
def get_property(property):  

or

object.property = value  
value =         


        
8条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-21 23:58

    You can use accessors/mutators (i.e. @attr.setter and @property) or not, but the most important thing is to be consistent!

    If you're using @property to simply access an attribute, e.g.

    class myClass:
        def __init__(a):
            self._a = a
    
        @property
        def a(self):
            return self._a
    
    

    use it to access every* attribute! It would be a bad practice to access some attributes using @property and leave some other properties public (i.e. name without an underscore) without an accessor, e.g. do not do

    class myClass:
        def __init__(a, b):
            self.a = a
            self.b = b
    
        @property
        def a(self):
            return self.a
    
    

    Note that self.b does not have an explicit accessor here even though it's public.

    Similarly with setters (or mutators), feel free to use @attribute.setter but be consistent! When you do e.g.

    class myClass:
        def __init__(a, b):
            self.a = a
            self.b = b 
    
        @a.setter
        def a(self, value):
            return self.a = value
    

    It's hard for me to guess your intention. On one hand you're saying that both a and b are public (no leading underscore in their names) so I should theoretically be allowed to access/mutate (get/set) both. But then you specify an explicit mutator only for a, which tells me that maybe I should not be able to set b. Since you've provided an explicit mutator I am not sure if the lack of explicit accessor (@property) means I should not be able to access either of those variables or you were simply being frugal in using @property.

    *The exception is when you explicitly want to make some variables accessible or mutable but not both or you want to perform some additional logic when accessing or mutating an attribute. This is when I am personally using @property and @attribute.setter (otherwise no explicit acessors/mutators for public attributes).

    Lastly, PEP8 and Google Style Guide suggestions:

    PEP8, Designing for Inheritance says:

    For simple public data attributes, it is best to expose just the attribute name, without complicated accessor/mutator methods. Keep in mind that Python provides an easy path to future enhancement, should you find that a simple data attribute needs to grow functional behavior. In that case, use properties to hide functional implementation behind simple data attribute access syntax.

    On the other hand, according to Google Style Guide Python Language Rules/Properties the recommendation is to:

    Use properties in new code to access or set data where you would normally have used simple, lightweight accessor or setter methods. Properties should be created with the @property decorator.

    The pros of this approach:

    Readability is increased by eliminating explicit get and set method calls for simple attribute access. Allows calculations to be lazy. Considered the Pythonic way to maintain the interface of a class. In terms of performance, allowing properties bypasses needing trivial accessor methods when a direct variable access is reasonable. This also allows accessor methods to be added in the future without breaking the interface.

    and cons:

    Must inherit from object in Python 2. Can hide side-effects much like operator overloading. Can be confusing for subclasses.

提交回复
热议问题