2009-12-10 2 views
8

나는 다양한 상태 플래그를 유지하기 위해 쓸모없는 "struct"객체를 만들고 싶었다.파이썬에서 struct 객체

>>> class Anon: pass 
... 
>>> b=Anon() 
>>> b.foo = 4 

나는 개체()가 __dict__이 없기 때문에이 추측 :이 작동하기 때문에 내 첫 번째 방법은,이 (자바 스크립트 스타일) 내가 기대했던 확실히

>>> status = object() 
>>> status.foo = 3 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'object' object has no attribute 'foo' 

하지 않았다. 사전을 사용하고 싶지 않고 Anon 개체를 만들고 싶지 않다고 가정하면 다른 해결책이 있습니까?

+2

http://stackoverflow.com/questions/1264833/python-class-factory-to-produce-simple-struct-like-classes –

+0

나는 파이썬 2.5를 사용하고 있으며, 어쨌든 명명 된 튜플은 내가 이해하는 한, 새로운 멤버를 나중에 동적으로 연결하는 것을 허용하지 않습니다. 주어진 예제에서 명확하지 않습니다. –

+0

@Stefano Borini : 기본적으로'foo [ 'bar']'대신'foo.bar'라고 말할 수있는 dict를 요구하고 있습니까? –

답변

21

"당신은/속성을 가져 할당 할 수있는에 일반 객체를"만드는 가장 간결한 방법은 아마도 대부분의 다른 답변이 지적으로

b = lambda:0 

, 거기에 여러 가지 방법이 있습니다,하지만 하드의 이 부분을 간결하게하기 위해 (lambda:0은 정확히 object() ...와 같은 문자 수입니다.

+20

당신이 무슨 도청인지 설명하는 문자를 계산하지 않으면! : D –

+0

와우! : D +1000 알렉스 –

+1

@Stefano, 고마워요! @gnibbler, 당신이 설명 할 필요가없는 람다는 충분히 신비 롭다. 공중에서 신비한 손가락 제스처를 만들고 모든 사람들은 두려움 속에서 물러 선다. (선택적으로 어둡게 불평하는 "람다, 궁극의 ...!", http : // lambda-the-ultimate.org/ 및/또는 http://en.wikipedia.org/wiki/Lambda를 참조하십시오). –

3

당신이 Python Official Documentation에서

>>> status=type('',(object,),{})() 
>>> status.__class__.__name__ 
'' 
+0

이것은 멋지고 해키이다. –

+0

미안하지만, 대답은 좋다. 그러나 Alex 'one은 나를 놀라게했다. :) –

+0

아무도 그 농담을 여기 보지 못했습니까? 'class status (object) : pass'와 같습니다. –

15

하지 않으려면이

>>> status=type('status',(object,),{})() 
>>> status.foo=3 
>>> status.foo 
3 

당신은 클래스 이름을 지정하지 않아도보십시오 :

9.7. 확율과 때로는, 파스칼 "레코드"또는 C "구조체"와 유사한 데이터 유형이 유용합니다 함께 몇 라는 이름의 데이터 항목을 번들

을 종료합니다. 빈 클래스 정의는 잘 할 것 :이 자연스럽고 간단한 것

class Employee: 
    pass 

john = Employee() # Create an empty employee record 

# Fill the fields of the record 
john.name = 'John Doe' 
john.dept = 'computer lab' 
john.salary = 1000 

: 파이썬을. Remember the Zen! (3 번)와 "구현이 설명하기 쉬운 경우, 좋은 생각이 될 수있다"(번호 11) 또한

struct 공공 회원들과 class에 불과하다 "단순 복잡보다 낫다" (즉, struct{};class{public:};은 정확히 같은 것입니다 (예를 들어, C++). 이것을 고려해서는 안되며 파이썬 프로그램에서 인공적인 구조를 피하는 것이 좋을까요? 파이썬은 읽기 쉽고 관리하기 쉬우 며 이해하기 쉽습니다.

+3

아,이 문서는 오래된 문서이며 정리해야합니다. 이 예제 코드는 "구식 클래스"를 만듭니다. 이것은 더 이상 권장되지 않으며 Python 3.x에서는 작동하지 않습니다. '클래스 직원 (객체) : pass' 당신이해야 할 모든입니다 , 그냥 object''에서 상속 파이썬 3.x를 작동하는 새로운 스타일의 클래스로이 정확한 예를 수행하려면 당신은 새로운 스타일의 수업을 가지고 있습니다. – steveha

+1

이것은 OP가 원하지 않는 Anon 예제와 정확히 같습니다. –

+0

네, 좋습니다. Status라는 클래스를 정의해야한다는 사실에 더 짜증이났다 : pass와 status = Status(). –

2

여기 미스테리 개체클래스 인스턴스 차이이다.

파이썬에서는 모든 것이 객체입니다. 클래스는 객체이고, 정수는 객체이며, 유형은 객체이며, 클래스 인스턴스는 객체입니다. object()라고 말하면 일반 기본 객체가 생성됩니다. 아무것도 아니야. 완전히 쓸모 없어. 파이썬에서 참조 할 수있는 것보다 낮은 레벨.

아마도 object()을 호출하면 클래스 인스턴스가 생깁니다. 이해할 수있는 것은 아마도 object이 수업이라고 생각했기 때문입니다. 그렇지 않습니다. 이 같은 새로운 스타일의 클래스 정의에 사용되는 기본 "클래스"이기 때문에 당신이 그렇게 생각할 수도 있지만 :

class MyClass(object): 
    pass 

object 사실 (strint이 유형 얼마나 같이) 유형입니다.object()으로 전화를 걸면 클래스 인스턴스를 구성하지 않고 특수한 유형의 객체를 인스턴스화합니다. 그러나 object 님의 경우, 그것은 얼마나 완전하게 특별합니까 blah입니다.

클래스 인스턴스 만 도트 표기법을 사용하여 물건을 고정시킬 수 있습니다. 그것은 모든 사물의 일반적인 속성이 아닙니다. 그것이 사실 인 경우를 상상해보십시오! 문자열에 속성을 추가하는 것과 같은 미친 작업을 수행 할 수 있습니다.

s = "cat" 
s.language = "english" 

분명히 할 수 없습니다.

+3

'object()'는 인스턴스를 반환합니다. 때로는 고유 한 값이 필요한 경우에 사용합니다 –

8

나는 한 번 같은 질문을했다. 나는 메일 링리스트에서 그것을 물었고 Alex Martelli는 object이 파이썬에서 모든 상속의 기초라고 지적했다. object()이 고유 한 사전으로 클래스 인스턴스를 만든 경우 Python의 모든 객체는 자체 사전을 가져야하므로 메모리가 낭비됩니다. 예를 들어 TrueFalse은 개체입니다. 분명히 그들은 그들 자신의 사전을 필요로하지 않는다!

의 일종이 있다면 나는 행복 할 것이다 내장 된 파이썬 기능 내가 말할 단지 수있는 곳 :

x = struct() 
x.foo = 1 
x.bar = 2 

하지만 사소한는 struct() 작성 :

class struct(object): 
    pass 

을 아니면 수 약간 더 복잡한 것을 수행하십시오 :

class struct(object): 
    def __init__(self, **kwargs): 
     self.__dict__.update(kwargs) 

더 복잡한 것은 더 쉽게 할 수 있습니다. 입니다 :

x = struct(foo=1, bar=2) 
print(x.foo) # prints 1 
print(x.bar) # prints 2 
x.baz = 3 
print(x.baz) # prints 3 

을하지만 내가이 언어에 추가 가치가있는 것으로 간주되지 않은 추측 struct() 쓰기 너무 간단하다. 아마도 우리는 표준 기능을 collections 모듈에 추가해야 할 것입니다.

+0

파이썬 적 사고와 읽을 수있는 코드를 장려하기 위해'struct'를 사용합니다. '구조체'는 더 명확하게'클래스'이고 내장 함수 나 함수는 아닙니다. 그러나 나는 당신이 당신의 생각에 대해 당신이 새로운 "개인적인"builtin을 만들었다는 것을 알 수있다. 그것은 builtin'object' 클래스와 매우 비슷하다. 그리고 소문자'struct'는 더 단순 해 보인다. – hobs

+0

사실 저는이 프로그램을 프로그램에 쓸 때이 평범한 클래스 'Box()'를 호출합니다. 여기서는 내장 함수를 제안했고, 파이썬 내장 함수는 ('deque'와 같이) 소문자가 아닌 경우를 제외하고는 ('Counter'와 같이) 소문자입니다. 나는 클래스 이름을 대문자로하는 것을 선호하지만, 나는 대답을 편집하지 않을 것이라고 생각한다. – steveha

+0

@steveha Python 내장 함수의 케이스는 구현 된 언어를 나타냅니다. C로 구현 된 경우 모두 소문자이지만 Python으로 구현되는 경우 ClassCased입니다. 자세한 내용은이 답변 (http://stackoverflow.com/a/14974045/1490091)을 참조하십시오. –

4

는 개인적으로 깨끗한 솔루션은 이미 짐작 무엇이라고 생각 :

class Scratch(object): 
    pass 

s = Scratch() 
s.whatever = 'you want' 

나는 당신이 __dict__을 원하지 않는다고 말했다 알고,하지만 난에 대한 이유를 볼 수있는 그 날 혼란 그것에 대해 신경써. 내부 파이썬 구현 세부 사항 인 __dict__을 참조 할 필요가 없습니다. 어쨌든 파이썬에서 동적으로 속성을 추가 할 수있는 인스턴스는 파이썬이 동적 속성을 수행하는 방식이기 때문에 __dict__이됩니다. 인스턴스가 실제로 영리한 방법으로 작성된 경우에도 __dict__이됩니다.

아직 작성하지 않았다면 PEP 20과 PEP 8을 읽는 것이 좋습니다 (평판이 나지 않으므로 나를위한 링크는 하나뿐입니다). PEP가 귀하의 질문과 직접 ​​관련이있는 것은 아니지만 사용하기에 유용하다고 생각합니다. 파이썬은 Pythonic 방식입니다.

2

물론 항상 namedtuple이 있습니다. 값이 싸고 빠르지 만 변경할 수 없습니다. 속성 이름과 값을 미리 알아야하며 나중에 값을 변경할 수 없습니다. 하지만 최소한 struct/object 속성 getters가 있습니다. 그리고 파이썬이 도와 드리겠습니다 3

>>> from collections import namedtuple 
>>> Status = namedtuple('Status', 'a b') 
>>> s = Status(a=1, b=2) 
>>> s.a + s.b 
3 
1

당신은 자바 스크립트 객체의 의미, 당신은 namespaces library를 사용하여 고려할 수 있습니다합니다. 먼저 pip install namespaces이 필요합니다.

>>> import namespaces as ns 
>>> b = ns.Namespace() 
>>> b.foo = 4 
>>> b 
Namespace(foo=4) 

전체 면책 조항 : 나는 namespaces 라이브러리의 저자입니다.