programing tip

파이썬“속성”과“속성”의 차이점은 무엇입니까?

itbloger 2020. 7. 18. 10:37
반응형

파이썬“속성”과“속성”의 차이점은 무엇입니까?


나는 일반적으로 "속성"과 "속성"의 차이점에 대해 혼란스러워하며 차이점을 간결하게 자세히 설명 할 수있는 훌륭한 자료를 찾을 수 없습니다.


속성은 특별한 종류의 속성입니다. 기본적으로 Python에서 다음 코드가 발생하면

spam = SomeObject()
print(spam.eggs)

그것은 조회 eggs에서 spam, 다음 검사 eggs그것은이 있는지 __get__, __set__또는 __delete__방법을 - 그것은 않는 경우,이 속성입니다. 이 경우 이다 속성, 대신 복귀의 eggs개체가 호출 (다른 속성은 마찬가지로) __get__방법 및 반환 무엇이든 그 메소드가 리턴 (우리는 조회를 수행 되었기 때문에).

에 대한 자세한 내용 파이썬의 데이터 모델 및 설명 .


속성을 사용하면 속성이없는 (주의 사항을 사용하지 않는 경우) getter, setter 및 deleter 메서드를 완전히 제어 할 수 있습니다.

class A(object):
    _x = 0
    '''A._x is an attribute'''

    @property
    def x(self):
        '''
        A.x is a property
        This is the getter method
        '''
        return self._x

    @x.setter
    def x(self, value):
        """
        This is the setter method
        where I can check it's not assigned a value < 0
        """
        if value < 0:
            raise ValueError("Must be >= 0")
        self._x = value

>>> a = A()
>>> a._x = -1
>>> a.x = -1
Traceback (most recent call last):
  File "ex.py", line 15, in <module>
    a.x = -1
  File "ex.py", line 9, in x
    raise ValueError("Must be >= 0")
ValueError: Must be >= 0

일반적으로 용어와 속성은 같습니다. 그러나 파이썬에는 속성 (또는 다른 데이터)에 대한 getter / setter 액세스를 제공하는 속성 데코레이터가 있습니다.

class MyObject(object):
    # This is a normal attribute
    foo = 1

    @property
    def bar(self):
        return self.foo

    @bar.setter
    def bar(self, value):
        self.foo = value


obj = MyObject()
assert obj.foo == 1
assert obj.bar == obj.foo
obj.bar = 2
assert obj.foo == 2
assert obj.bar == obj.foo

이 속성을 사용하면 일반 속성처럼 값을 가져오고 설정할 수 있지만 그 아래에는 getter 및 setter로 변환하는 메소드가 있습니다. 게터와 세터를 호출하는 상용구를 줄이는 것이 정말 편리합니다.

예를 들어, 필요한 것에 대해 x와 y 좌표를 보유한 클래스가 있다고 가정 해 봅시다. 그것들을 설정하기 위해 다음과 같은 작업을 원할 수 있습니다.

myObj.x = 5
myObj.y = 10

That is much easier to look at and think about than writing:

myObj.setX(5)
myObj.setY(10)

The problem is, what if one day your class changes such that you need to offset your x and y by some value? Now you would need to go in and change your class definition and all of the code that calls it, which could be really time consuming and error prone. The property allows you to use the former syntax while giving you the flexibility of change of the latter.

In Python, you can define getters, setters, and delete methods with the property function. If you just want the read property, there is also a @property decorator you can add above your method.

http://docs.python.org/library/functions.html#property


I learnt 2 differences from site of Bernd Klein, in summary:

1. Property is a more convenient way to do data encapsulation.

ex: If your have a public attribute lenght of Object, later on, your project requires you to encapsulate it, i.e: change it to private and provide getter and setter => you have to change many of the codes you wrote before:

#Old codes
obj1.length=obj1.length+obj2.length
#New codes(Using private attibutes and getter and setter)
obj1.set_lenght(obj1.get_length()+obj2.get_length()) #=> this is ugly

If you use @property and @lenght.setter => you don't need to change those old codes

2. A property can encapsulate multiple attributes

class Person:
  def __init__(self, name, physic_health, mental_health):
    self.name=name
    self.__physic_health=physic_health #physic_health is real value in range [0, 5.0]
    self.__mental_health=mental_health #mental_health is real value in range [0, 5.0]
  @property
  def condition(self):
    health=self.__physic_health+self.__mental_health
    if(health<5.0):
      return "I feel bad!"
    elif health<8.0:
      return "I am ok!"
    else:
      return "Great!"

In this example, __physic_health and __mental_health are private and can not be accessed directly from out side, the only way outside class interact with them is throught property condition


There is also one not obvious difference that i use to cache or refresh data , often we have a function connected to class attribute. For instance i need to read file once and keep content assigned to the attribute so the value is cached:

class Misc():
        def __init__(self):
            self.test = self.test_func()

        def test_func(self):
            print 'func running'
            return 'func value'

cl = Misc()
print cl.test
print cl.test

Output:

func running
func value
func value

We accessed the attribute twice but our function was fired only once. Changing the above example to use property will cause attribute's value refresh each time you access it:

class Misc():

    @property
    def test(self):
        print 'func running'
        return 'func value'

cl = Misc()
print cl.test
print cl.test

Output:

func running
func value
func running
func value

참고URL : https://stackoverflow.com/questions/7374748/whats-the-difference-between-a-python-property-and-attribute

반응형