Python에 익명의 클래스가 있습니까?
파이썬에 C # 익명 클래스 기능과 같은 것이 있는지 궁금합니다. 명확히하기 위해 다음은 샘플 C # 스 니펫입니다.
var foo = new { x = 1, y = 2 };
var bar = new { y = 2, x = 1 };
foo.Equals(bar); // "true"
Python에서는 다음과 같이 상상할 수 있습니다.
foo = record(x = 1, y = 2)
bar = record(y = 2, x = 1)
foo == bar # true
특정 요구 사항은 표현식 컨텍스트에서 지정된 필드 (예 : 람다 및 문이 허용되지 않는 기타 장소에서 사용 가능)가있는 객체를 생성 할 수 있어야하며, 추가 외부 선언없이 일반 멤버를 통해 이름별로 개별 구성 요소에 액세스 할 수 있어야합니다. 액세스 구문 foo.bar
. 생성 된 객체는 구성 요소 이름 (튜플처럼 위치가 아닌)으로 구조적 비교 를 구현해야합니다 .
특히 : 튜플은 구성 요소의 이름이 지정되지 않았기 때문에 그렇지 않습니다. 클래스는 선언이 필요하기 때문에 그렇지 않습니다. dicts는 foo["bar"]
구성 요소에 액세스하는 데 원하지 않는 구문 이 있기 때문에 그렇지 않습니다 .
namedtuple 은 그렇지 않습니다. 유형을 인라인으로 정의하더라도 여전히 이름이 필요하고 비교는 이름 기반이 아니라 위치 기반이기 때문입니다. 특히:
def foo(): return namedtuple("Foo", "x y")(x = 1, y = 2)
def bar(): return namedtuple("Foo", "y x")(x = 1, y = 2)
foo() == bar() # False because fields are compared in order, and not by name
# True would be desired instead
필요한 경우 파이썬으로 그런 것을 작성하는 방법을 알고 있습니다. 하지만 Python 표준 라이브러리 나 인기있는 타사 라이브러리에 이와 같은 것이 있는지 알고 싶습니다.
[편집하다]
이를 위해 Ken과 alanlcode의 두 가지 매우 유익한 답변을 결합하여 추가 외부 선언없이 구조적 동등성을 생성하는 단일 표현식 솔루션이 있습니다.
type("", (), { \
"__init__": (lambda self, **kwargs: self.__dict__.update(kwargs)), \
"__eq__": (lambda self, other: self.__dict__ == other.__dict__) } \
)(x = 1, y = 2)
기술적으로는 질문의 모든 요구 사항을 충족하지만 아무도 사용하지 않기를 진심으로 바랍니다.
파이썬적인 방법은 다음을 사용하는 것입니다 dict
.
>>> foo = dict(x=1, y=2)
>>> bar = dict(y=2, x=1)
>>> foo == bar
True
foo['x']
대신 해야 할 일을 제외하고 모든 요구 사항을 충족합니다 foo.x
.
이것이 문제라면 다음과 같은 클래스를 쉽게 정의 할 수 있습니다.
class Bunch(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)
def __eq__(self, other):
return self.__dict__ == other.__dict__
또는 멋지고 짧은
class Bunch(dict):
__getattr__, __setattr__ = dict.get, dict.__setitem__
(그러나 Alex가 자신의 의견에서 지적했듯이이 두 번째 문제에는 문제가 있습니다!)
1) http://uszla.me.uk/space/blog/2008/11/06을 참조하십시오 . type
내장 함수를 사용하여 약간보기 흉한 구문으로 익명 객체를 만들 수 있습니다 .
anon_object_2 = type("", (), {})()
여기서 세 번째 매개 변수는 개체의 필드를 포함 할 사전입니다.
foo = type("", (), dict(y=1))()
foo.y == 1
2) http://norvig.com/python-iaq.html 에서 Peter Norvig에 의해 또 다른 변형이 제안되었습니다 . 또한 Ken이 게시 한 답변과 유사합니다.
class Struct:
def __init__(self, **entries): self.__dict__.update(entries)
>>> options = Struct(answer=42, linelen = 80, font='courier')
>>> options.answer
42
이 방법의 장점은 첫 번째 옵션에는없는 dict의 내용으로 동등성을 구현할 수 있다는 것입니다.
파이썬 3.3이 정확히 이것을 types.SimpleNamespace
클래스 형태로 추가 한 것 같습니다 .
type (...) 형식은 구조적 비교 요구 사항에 실패합니다 (정말 추악하지 않음). dict (...) 양식이 속성 접근 자 요구 사항을 충족하지 않습니다.
attrdict는 중간 어딘가에 떨어질 것 같다 :
class attrdict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.__dict__ = self
a = attrdict(x=1, y=2)
b = attrdict(y=2, x=1)
print a.x, a.y
print b.x, b.y
print a == b
그러나 그것은 특별한 클래스를 정의하는 것을 의미합니다.
OK, I just noticed the update to the question. I'll just note that you can specify dict
for the bases parameter and only need to specify the constructor then (in the icky type expression). I prefer attrdict. :-)
I don't remember offhand if there's a built-in but writing it yourself is shorter than typing your question. :-)
class record(object):
def __init__(self, **kwargs): self.__dict__ = kwargs
def __eq__(self, r2): return self.__dict__ == r2.__dict__
def __ne__(self, r2): return self.__dict__ != r2.__dict__
foo = record(x=1, y=2)
bar = record(y=2, x=1)
foo == bar # => true
If you want the instance to be anonymous as well (using the object directly in an expression), then you're bound to use the type-expression. However in many cases the instance will not be anonymous, but assigned to a variable. This case can be handled in a reasonable way in python by using metaclasses or decorators.
An example using decorator:
def anonymous(cls):
return cls()
@anonymous
class foo:
x = 42
def bar(self):
return self.x
The decorator in this case causes the class foo
to be instantiated an put into the variable foo
instead of the class itself. The class itself will not be accessible from any namespace although it has a name:
>>> foo
<__main__.foo instance at 0x7fd2938d8320>
>>> foo.bar()
42
Another feature in python that accomodates for many use cases is that it's legal to define classes locally, which means that they would become a symbol local to that function, which in turns gives it some degree of anonymity.
Quoted from this page:
class Struct:
def __init__(self, **entries): self.__dict__.update(entries)
def __eq__(self, other): return self.__dict__ == other.__dict__
def __ne__(self, other): return self.__dict__ != other.__dict__
options = Struct(answer=42, linelen = 80, font='courier')
options.answer
>>> 42
options.answer = 'plastics'
vars(options)
>>> {'answer': 'plastics', 'font': 'courier', 'linelen': 80}
As show above, I get a good intellisense from pycharm for this and I love this solution...
>>> def anonymous(cls):
... return cls()
>>> class fooo:
... @anonymous
... class c:
... D=10
>>> fooo.c.D
10
참고URL : https://stackoverflow.com/questions/1123000/does-python-have-anonymous-classes
'developer tip' 카테고리의 다른 글
Keycloak의 OAuth2 / OpenID Connect 엔드 포인트는 무엇입니까? (0) | 2020.11.14 |
---|---|
Visual Studio에서 '웹 사이트'와 '프로젝트'의 차이점 (0) | 2020.11.14 |
JavaScript : 문자열 부울 값 구문 분석? (0) | 2020.11.14 |
Vim에서 다른 텍스트 열 뒤에 텍스트 열을 어떻게 붙여 넣나요? (0) | 2020.11.14 |
테이블 셀의 최대 높이를 설정하는 방법은 무엇입니까? (0) | 2020.11.14 |