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


146

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

답변:


184

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

spam = SomeObject()
print(spam.eggs)

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

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


속성에 목표 값에 액세스하기위한 추가 처리가 필요한 것 같습니다.
martineau

@martineau : 글쎄, 추가 함수 호출이 하나 있지만, 추가 작업과 시간은 속성이 수행하는 작업의 양에 따라 다릅니다 (일반적인 조언 : I / O를 숨기려면 속성 사용 / 사용 안함).
Ethan Furman 2016 년

56

속성을 사용하면 속성이없는 (주의 사항을 사용하지 않는 경우) 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

그러나 이러한 단순한 데코레이터없이 "비 속성"속성으로도이 "완전한 제어"를 수행 할 수 있습니다.

8
이 답변이 현실적이고 유용한 예를 제공한다는 것을 좋아합니다. 이 사이트에 대한 답변이 너무 많으면 사용자가 어떻게 상호 작용해야하는지 명확하게 설명하지 않고 백엔드에서 어떻게 작동하는지 설명 할 수 있습니다. 왜 / 어떤 기능을 사용해야하는지 이해하지 못한다면 어떻게 작동하는지 알 수 없습니다.
Tom

이 답변은 "파이썬 젠 (Zen of Python)-명백한 방법이 있어야한다"는 것을 위반한다. x 값을 설정하는 방법은 2 가지가 있습니다.
Tin Luu

@TinLuu-x 값을 설정하는 유일한 방법이 있습니다. _x 값을 설정하는 방법은 하나뿐입니다. 그것들이 같은 사실은 구현 세부 사항입니다. 이 클래스의 현명한 사용자는 _x를 사용하지 않습니다.
조명

1
@ TinLuu-나는 우리가 관점의 반대편 끝에서 같은 것을 말하는 것 같아요. 클래스 사용자는을 참조하십시오 x. 일방 통행. 클래스의 사용자가 _x에 대해 알게되면 스스로 위험을 감수해야합니다.
조명 된

19

일반적으로 용어와 속성은 같습니다. 그러나 파이썬에는 속성 (또는 다른 데이터)에 대한 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

1
이 코드의 예상 결과에 대해서도 말씀해 주시겠습니까?
Hasan Iqbal

2
무슨 소리 야? 코드 하단에 있지 않습니까?
six8

12

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

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

myObj.x = 5
myObj.y = 10

글을 쓰는 것보다보고 생각하기가 훨씬 쉽습니다.

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

문제는 언젠가 수업이 바뀌어 x와 y를 어떤 값으로 상쇄해야 하는가? 이제 클래스 정의와이를 호출하는 모든 코드를 변경하고 변경해야하므로 시간이 많이 걸리고 오류가 발생할 수 있습니다. 이 속성을 사용하면 이전 구문을 사용할 수 있으며 후자의 변경 유연성을 제공 할 수 있습니다.

Python에서는 속성 함수를 사용하여 getter, setter 및 delete 메소드를 정의 할 수 있습니다. read 속성 만 원한다면 메소드 위에 추가 할 수있는 @property 데코레이터도 있습니다.

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


실용적인 의미의 대답 만!
Dude156

8

Bernd Klein 사이트 와 2 가지 차이점을 요약 해서 배웠습니다 .

1. 속성은 데이터 캡슐화를 수행하는보다 편리한 방법입니다.

예 : 공개 속성 길이가 Object 인 경우 나중에 프로젝트에서 캡슐화해야합니다. 즉, 개인으로 변경하고 getter 및 setter를 제공하십시오 => 이전에 작성한 많은 코드를 변경해야합니다.

#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

@property 및 @ lenght.setter =>를 사용하면 이전 코드를 변경할 필요가 없습니다.

2. 속성은 여러 속성을 캡슐화 할 수 있습니다

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!"

이 예에서 __physic_health__mental_health개인 그리고면이 바깥을 향하게에서 직접 액세스 할 수없는, 그들과 함께있는 유일한 방법은 외부 클래스 상호 작용을 축복하는 속성입니다condition


8

또한 데이터를 캐시하거나 새로 고치는 데 사용하는 명백한 차이점은 없지만 클래스 속성에 연결된 함수가 있습니다. 예를 들어 파일을 한 번 읽고 속성에 할당 된 내용을 유지해야 값이 캐시됩니다.

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

산출:

func running
func value
func value

속성에 두 번 액세스했지만 함수는 한 번만 발생했습니다. 속성을 사용하도록 위 예제를 변경하면 속성에 액세스 할 때마다 속성 값이 새로 고쳐집니다.

class Misc():

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

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

산출:

func running
func value
func running
func value
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.