2013-01-15 4 views
2

각 범주마다 다른 이름을 가진 범주 클래스가 있습니다. 범주 이름은 알 수 없거나 좋고 나쁨, 모든 범주는 동일한 동작을 공유하므로 만들지 않습니다.파이썬에서 정적 속성으로 개체 만들기

Category.GOOD 

이 문을 그래서 시도 그의 이름이 '좋은'로 설정하여 범주 객체를 반환해야합니다 :이 방법으로 다른 카테고리를 만들 하려고 할 때 카테고리의 각 유형에 대한 하위 클래스는 문제가 온다 다음 :

class Category(object):                            

    def __init__(self, name):                          
     self.name = name                           

    @property 
    def GOOD(self): 
     category = Category(name='good')                       
     return category                            

    @property 
    def BAD(self): 
     category = Category(name='bad')                        
     return category 

그럼 내가 만들어 다음과 같은 출력 범주를 사용

class Category(object):                           

    GOOD = Category(name='good') 
    BAD = Category(name='bad')                         

    def __init__(self, name): 
     self.name = name 

무엇 내가 여기에 도착하는 것은 정의되지 않은 이름입니다 : 내가 접근과 같은 자바를 시도 작동하지 않습니다

c = Category.GOOD 
c.name 
AttributeError: 'property' object has no attribute 'name' 

이 있음을 깨닫고 "카테고리"오류, 그래서 내 질문은 거기에 이런 종류의 개체를 만드는 pythonic 방법입니다.

+0

을; 대신 자신 만의 디스크립터를 생성하거나,'classmethod'를 사용하고 아래에 주어진대로'GOOD()'을 호출해야한다. –

+0

@MartijnPieters -이 동작으로 설명자를 만들 수 없습니까? 문제는 그가 클래스의 디스크립터에 접근하고 있다는 것입니다 (단지 속성 일 뿐이며 특별한 디스크립터 마법도 사용되지 않습니다). – mgilson

+0

@mgilson : 클래스에 대해서도 디스크립터가 호출됩니다. 'classmethod' 역시 기술자입니다. 'function .__ get __ (None, cls)'는 파이썬 2에서 '언 바운드 메소드'를 제공합니다 (파이썬 3에서'self'를 반환합니다). 그래서 확실히 호출됩니다! –

답변

1

이 경우 모듈 변수를 사용합니다. 당신이 그것에 두 개의 전역 개체를 넣어 지금

class Category(object): 
    # stuff... 

:

GOOD = Category(name='good') 
BAD = Category(name='bad') 

당신은 그런 식으로 사용할 수 있습니다 :

from path.to.category import GOOD, BAD 

내가 말을하지 않습니다 당신이 모듈 category.py을 고려 이것은 pythonic입니다. 그러나이 접근법은 우아하다고 생각합니다. 이제 을 할 수

class Category(object): 

    @classmethod 
    def GOOD(cls): 
     category = cls(name='GOOD') 
     return category 

:

2

당신은 아마 classmethods를 사용하고 싶습니다.

0

해당 클래스 정의 자체에서 클래스 정의를 사용할 수 없다는 요점. 그래서 당신이 원하는 것을 얻기위한 가장 직접적인 방법은 아래와 같이 클래스/정적 메소드를 사용하거나 패키지 상수를 사용하는 것입니다.

class Category(object): 
    def __init__(self, name): 
     self.name = name 

    @classmethod 
    def GOOD(cls): 
     return Category(name='good') 

    @classmethod 
    def BAD(cls): 
     return Category(name='bad') 

print Category.GOOD().name 

또는

class Category(object): 
    def __init__(self, name): 
     self.name = name 

    @staticmethod 
    def GOOD(): 
     return Category(name='good') 

    @staticmethod 
    def BAD(): 
     return Category(name='bad') 

print Category.GOOD().name 
+0

테스트 해 보셨습니까? 여기에 * 좋은 * 전화를해야합니다 ... – mgilson

+0

당신 말이 맞아요 - 그냥 다른 아이디어를 테스트에서 코드를 복사. 결정된. 고맙습니다. – Vladimir

+0

부수적으로, 나는 모든 대문자에'좋은 (GOOD) '이라고 쓰는 것을 좋아하지 않았다. 그것은 소리 지르는 것 같았습니다 ... 어떤 경우에도, 이것은 지금 바르게 보입니다. – mgilson

2
당신은 속성이 작업을 수행 할 수

; 당신은 classmethod를 사용하는, 또는 그것에 대한 자신의 descriptor 작성 중 하나

class classproperty(property): 
    def __get__(self, inst, cls): 
     return self.fget(cls) 

내가 여기 property 장식을 남용하고 있습니다를; 그것은 __set____del__을 구현하지만, 편의상 여기서는 무시할 수 있습니다.

그런 다음 property 대신 그것을 사용

class Category(object): 
    def __init__(self, name): 
     self.name = name 

    @classproperty 
    def GOOD(cls): 
     return cls(name='good') 

    @classproperty 
    def BAD(cls): 
     return cls(name='bad') 

지금 Category.GOOD 작품에 접근 :이 아웃 - 오브 - 박스 앞에`property`과 함께 할 수 없습니다

>>> Category.GOOD 
<__main__.Category object at 0x10f49df50> 
>>> Category.GOOD.name 
'good' 
+0

Upvoted. 뒷쪽에서는 클래스 메쏘드 (classmethod) 나 정적 메쏘드 (staticmethod)를 사용하기 위해 기술자가 클래스 (그리고 단지 인스턴스가 아닌)에 대해 작업해야한다는 것이 분명해 보인다. 두 달 전에 기술자를 가르친 이래로 이런 것들에 대한 잘못된 생각을 가지고 있다고 생각합니다 ... – mgilson

관련 문제