python/3의class/metaclass의DSL 응용

5098 단어 Pythonmetaclasstech
별편 보도에서도pyhon2/3에서'class 정의'는 엄격하게 말하면 type 클래스의 실례 생성이고'이른바 실례 생성'처럼 보이는 것은 type 클래스의 집행이라고 썼다.
반대로'class 정의를 사용하여'class가 아닌 것'을 만들 수 있다'고 말한다. 예를 들어 그 중 하나는 enum이다.

lib/enum의 경우


대화의 시작으로 적당한 실례가 있으면 비교적 편리하니 공식 문서를 사용할 수 있도록 허락해 주십시오.
8.13. enum - 열거 지원 - Python 3.3.5.5 문서
python3.5에서 엔음이 추가되었습니다.여기서 서술하고 있다.하지만 실제로 시도해 보니 겉으로는class 정의만 보인다.예를 들어, 위의 문서에는 다음과 같은 소스가 있습니다.
class Color(Enum):
     red = 1
     green = 2
     blue = 3
Color는 이 정의로 단일체로 완성되어 구조기가 없고 부르고 싶어도 작동하지 않습니다.이런 의미에서'반'이 아니다.그러나python 3의 문법은 아무리 봐도 클라스 정의다.
그리고 컬러는레드에서 정수 1을 정의해야 하지만 사용할 때 대상입니다.

역방향 공사를 시험해 보다


jupyther-notebook 등 사이트에서 적당한 enum을 만들고 실례를 뒤집어 보면 재미있다.
우선 적당히 정의해 보세요.
from enum import Enum,auto
class httpmethod(Enum):
    HEAD=0
    GET=auto()
    POST=auto()
    PUT=auto()
    DELETE=auto()
그런 다음 덤프합니다.
httpmethod.__dict__
정의보다 더 많은 정보가 나타날 것이다.
mappingproxy({'_generate_next_value_': <function enum.Enum._generate_next_value_(name, start, count, last_values)>,
              '__module__': '__main__',
              '__doc__': 'An enumeration.',
              '_member_names_': ['HEAD', 'GET', 'POST', 'PUT', 'DELETE'],
              '_member_map_': {'HEAD': <httpmethod.HEAD: 0>,
               'GET': <httpmethod.GET: 1>,
               'POST': <httpmethod.POST: 2>,
               'PUT': <httpmethod.PUT: 3>,
               'DELETE': <httpmethod.DELETE: 4>},
              '_member_type_': object,
              '_value2member_map_': {0: <httpmethod.HEAD: 0>,
               1: <httpmethod.GET: 1>,
               2: <httpmethod.POST: 2>,
               3: <httpmethod.PUT: 3>,
               4: <httpmethod.DELETE: 4>},
              'HEAD': <httpmethod.HEAD: 0>,
              'GET': <httpmethod.GET: 1>,
              'POST': <httpmethod.POST: 2>,
              'PUT': <httpmethod.PUT: 3>,
              'DELETE': <httpmethod.DELETE: 4>,
              '__new__': <function enum.Enum.__new__(cls, value)>})
그중에 정의된 기억은 뒷부분의 몇 개뿐이지만 보기에 편리해 보이는 값이 많이 증가한 것을 알 수 있을 것이다.
  • _member_names_ 문자열 이름의 열거 정의하기
  • _member_map_ 명칭-상수 실례 인용표
  • _value2member_map_ 상수 실례에서 수치까지의 인용표
  • 그럼Enum은 도대체 뭘 한 거야?
    /usr/lib/python/enum.일부분py를 발췌하다
    class EnumMeta(type):
    
    class Enum(metaclass=EnumMeta):
        """Generic enumeration.
    
    상기 학급이 직접 계승한 것은 엔움이지만 엔움에는 메타클라스=엔umMeta의 기술이 있고 엔umMeta류는 type에서 계승한다.
    이 metaclass의 명칭 파라미터는 간이지만, 사실class가 정의할 때마다 metaclass 파라미터를 사용할 수 있습니다.
    기본값은 type입니다.
    이것은 통상적으로'class를 정의하면 type 실례를 만들 수 있기 때문이다'.
    class 정의 시 EnumMetanew__ 개입,class 정의의 내용을 가공합니다.
    github의 원본에서 쉽게 참고할 수 있습니다.앞에 표 만드는 것도 알지?
    cpython/enum.py at 3.9 · python/cpython
    또 auto()의 열거수 전개도 이곳에서 진행된다.
    다국어 신도들이 보기에는'인기가 없다'는 경우가 많지만, 그 기능이 매우 단순하고 다양성이 이뤄져 놀랍다.

    좋은 웹페이지 즐겨찾기