어느 시점에서 당신은 많은 논증을 가진 함수들을 보게 될 것입니다. 때로는 일부 주장을 수퍼 인수로 결합하는 것이 합리적입니다. 나는 종종 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)
단점은 무엇입니까? 사실 a
과 b
잘 입력되지 않습니다? 그들은 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()
대신 속성 값을 비교합니다.