python 노트 (3) 모델

5084 단어
1
이전 글 은 정규 표현 식 을 말 했 습 니 다. 내용 은 기본적으로 시스템 문서 에서 나 왔 습 니 다. 여기 서 예 를 들 어 모드 해석 기 를 만들어 야 합 니 다.먼저 간단 한 모델 을 보 세 요.
Hello {{name}}

우리 의 임 무 는 name 을 우리 가 지정 한 이름 으로 바 꾸 는 것 입 니 다. 여기 {}} 을 태그 기호 로 하 는 것 입 니 다.템 플 릿 은 여러 곳 에서 사용 되 었 는데 주로 교체 작업 을 찾 고 복잡 한 논리 구 조 를 가 집 니 다.논리 적 구 조 를 가 진 모드:
{if a>b}
       a  b
{end if}

순환 구조 가 있 는 모드:
{for a in names}
{{a}}
{end for}

2
  • 변수 출력 문 {{}} 이 임 무 는 어떻게 해 야 합 니까? 가장 간단 한 것 부터 먼저 내용 을 찾 은 다음 에 교체 해 야 합 니 다.
  • def translate(template,context)
    

    위 에서 저 는 함 수 를 정 의 했 습 니 다. 이 함 수 는 모델 을 받 아들 인 다음 에 모델 에서 관련 내용 을 분석 하고 context 에서 해당 하 는 값 을 가 져 옵 니 다.
    str ='{{name}}is {{age}} years old'
    pattern = re.compile(r'{{(.*?)}}')
    context = {'name':'dongge','age':18}
    def lookup(m):
        try:
            key = m.group(1)
            if key in context:
                return "{}".format(context[key])
        except Exception as e:
            return ""
    pattern.sub(lookup,test_str)
    'donggeis 18 years old'
    
  • 처리 조건 문
  • pif = re.compile(r'{\s*?if\s+(?P.+?)\s*?}(?P.*?){\s*?end\s+?if\s*?}',re.MULTILINE)
    test_str = '{if 1>2}hhh{end if}'
    m=pif.search(test_str)
    m.groupdict()
    #{'cond': '1>2', 'content': 'hhh'}
    def calccond(cond,context):
        try:
            return eval(cond,context)
        except Exception as e:
            return False
    cond = m.group('cond')
    calccond(cond,None)
    #False
    
  • 순환 문 처리
  • pfor = re.compile(r'{\s*?for\s+(?P.+?)\s+in\s+(?P.+?)\s*?}(?P.*?){\s*?end\s+?for\s*?}',re.MULTILINE)
    test_str='{for a in names}\
    hello\
    {end for}'
    m=pfor.search(test_str)
    m.groupdict()
    #{'content': 'hello', 'val': 'a', 'vals': 'names'}
    def executefor(m,context):
        content = m.group('content')
        val = m.group('val')
        vals = m.group('vals')
        if vals in context:
            vals = context[vals]
        else:
            vals = []
        for v in vals:
            context[val] = v
            ....
        return ...
    

    위의 코드 는 세 가지 기능 에 초 략 적 으로 실현 되 었 으 나, 여기에 약간의 문제 가 존재 한다.출력 기능 은 간단 한 문장 에 속 하고 조건 과 순환 문장 은 복합 문장 에 속한다.
    3
    실제 모드 처리 에서 우 리 는 정규 표현 식 으로 세 가지 상황 을 함께 처리 할 것 입 니 다. 그러면 이 표현 식 들 은 바로 또는 관계 입 니 다.
    token_specification = [('exp',r'{{.*?}}'),
    ('ifstmt',r'{\s*?if\s+.+?\s*?}.*?{\s*?end\s+?if\s*?}'),
    ('forstmt',r'{\s*?for\s+.+?\s+in\s+.+?\s*?}.*?{\s*?end\s+?for\s*?}')]
    tok_regex = '|'.join('(?P%s)' % pair for pair in token_specification)
    p_temp = re.compile(tok_regex)
    

    위의 코드 는 세 가지 상황 에서 정규 표현 식 을 보 여 주 었 습 니 다. | 으로 이 표현 식 을 연결 하 였 습 니 다. 여기 서 세 가지 상황 에서 표현 식 의 이름 을 붙 여 주 었 습 니 다. 이렇게 하면 나중에 구분 하 는 것 이 도대체 그런 표현 식 인지 식별 할 수 있 습 니 다.
    import re
    p_exp = re.compile(r'{{(?P.*?)}')
    p_if = re.compile(r'{\s*?if\s+(?P.+?)\s*?}(?P.*?){\s*?end\s+?if\s*?}')
    p_for = re.compile(r'{\s*?for\s+(?P.+?)\s+in\s+(?P.+?)\s*?}(?P.*?){\s*?end\s+?for\s*?}')
    def render_template(template,context):
        def replace_fun(m):
            kind = m.lastgroup
            value = m.group(kind)
            if kind == 'exp':
                return handle_exp(value,context)
            elif kind == 'ifstmt':
                return handle_if(value,context)
            elif kind == 'forstmt':
                return handle_for(value,context)
        return p_temp.sub(replace_fun,template)
    

    주 함 수 는 render_template 입 니 다. 이 함수 에서 저 는 함 수 를 정 의 했 습 니 다.이 함 수 를 정의 하 는 이 유 는 sub 함수 의 첫 번 째 매개 변 수 는 match object 이지 만 표현 식 의 값 을 계산 하기 위해 서 는 문맥 정보 가 필요 하기 때 문 입 니 다.다음은 세 가지 상황 을 각각 처리 하 는 것 입 니 다. 표현 식 에 있어 서 가장 간단 하지만 조건 과 순환 문 구 는 복합 문 에 속 하기 때문에 이 함수 에서 주 함 수 를 호출 합 니 다.
    def handle_exp(template,context):
        m = p_exp.match(template)
        exp = m.group('exp')
        ret = eval(exp,context)
        return "{}".format(ret)
    
    def handle_if(template,context):
        print(template)
        m = p_if.match(template)
        cond = m.group('cond')
        content = m.group('content')
        ret = eval(cond,context)
        if isinstance(ret,bool) and ret:
            return render_template(content,context)
        return ''
    
    def handle_for(template,context):
        m = p_for.match(template)
        name = m.group('name')
        vals = m.group('vals')
        content = m.group('content')
        ret = eval(vals,context)
        rstr = []
        try:
            for v in ret:
                context[name] = v
                rstr.append(render_template(content,context))
        except Exception as e:
            print(e)
            return ''
        return ''.join(rstr)
    

    좋은 웹페이지 즐겨찾기