파이썬 3.4 이상에서 dict를 사용하지 않을 때 SimpleNamespace보다 namedtuple을 사용해야하는 이유는 매우 비슷합니다. 함수들을 보게

어느 시점에서 당신은 많은 논증을 가진 함수들을 보게 될 것입니다. 때로는 일부 주장을 수퍼 인수로 결합하는 것이 합리적입니다. 나는 종종 dicts 로이 작업을 수행했지만 이제는 더 나은 방법을 찾고 있습니다.

설정하고 싶습니다 …

def do_something(ax, ay, az, bu, bv, c):
    # Do something

…에 …

def do_something(a, b, c):
    # Do something

… 하위 변이를 포함 a하고 b포함합니다.

이를 수행하는 한 가지 방법은 다음을 수행하는 것입니다.

A = namedtuple('A', 'x, y, z')
a = A(ax, ay, az)
B = namedtuple('B', 'u, v')
b = B(bu, bv)

그러나 이것은 더 단순 해 보입니다.

a = SimpleNamespace(x=ax, y=ay, z=az)
b = SimpleNamespace(u=bu, v=bv)

단점은 무엇입니까? 사실 ab잘 입력되지 않습니다? 그들은 A와 B가 아닌가?

(Btw, 변수 이름에 대해 걱정하지 마십시오. 일반적으로 짧은 변수 이름으로 사용하지 않습니다.)



답변

SimpleNamespace기본적으로 사전 위에 멋진 외관입니다. 인덱스 키 대신 속성을 사용할 수 있습니다. 이것은 매우 유연하고 조작하기 쉽기 때문에 좋습니다.

이러한 유연성의 단점은 어떠한 구조도 제공하지 않는다는 것입니다. 누군가가 전화를하는 것을 막을 수있는 것은 없습니다 SimpleNamespace(x=ax, y=ay)(그리고 del a.z어느 시점에서). 이 인스턴스가 함수에 전달되면 필드에 액세스하려고 할 때 예외가 발생합니다.

반대로 namedtuple구조화 된 유형을 만들 수 있습니다. 유형에는 이름이 있으며 어떤 필드가 있어야하는지 알 수 있습니다. 해당 필드가 없으면 인스턴스를 만들 수 없으며 나중에 제거 할 수 없습니다. 또한 인스턴스는 변경할 수 없으므로의 값 a.x은 항상 동일 하다는 것을 알 수 있습니다.

SimpleNamespace제공 하는 유연성이 필요한지 또는에서 제공하는 구조 및 보증 을 원하는지 결정하는 것은 사용자의 책임입니다 namedtuple.


답변

나는 구조화 된 것과 그렇지 않은 것에 대한 대답을 정말로 좋아하므로 아래의 구체적인 예를 제공하고 있습니다.

SimpleNamespace로 시작하는 키를 허용합니다 _. 예를 들어 JSON을 필드 이름을 가진 객체로 제어하지 않는 빠르고 쉬운 방법을 찾고 있다면 매우 유용합니다.

d = {"_id": 2342122, "text": "hi there!"} # Elasticsearch gives this id!
e = SimpleNamespace(**d) # works
Name = namedtuple("Name", sorted(d)) # ValueError so we can't do Name(**d)

위의 사항을 통해 알 수 없는 namedtuple추가 개체를 얻을 수 있습니다 SimpleNamespace. 각각 SimpleNamespace은 실제로 “고유 한 눈송이”이지만, namedtuple구체적인 값으로 인스턴스화되지 않고 존재합니다. 구체적인 가치를 일반화하는 추상화가 필요한 경우에는이를 선호해야합니다.


답변

요약 SimpleNamespace

객체를 구성하는 동안 속성을 초기화 할 수 있습니다.

sn = SimpleNamespace(a=1, b=2)

그것은 읽을 수 있습니다

repr(): eval(repr(sn)) == sn

기본 비교를 무시합니다. 로 비교하는 id()대신 속성 값을 비교합니다.