ProgramingTip

Python : ".. % (var) s .."% locals ()를 사용하는 것이 좋은 방법입니까?

bestdevel 2020. 11. 1. 18:28
반응형

Python : ".. % (var) s .."% locals ()를 사용하는 것이 좋은 방법입니까?


나는이 패턴 (또는 안티 패턴)을 발견하고 매우 만족합니다.

매우 민첩하다고 생각합니다.

def example():
    age = ...
    name = ...
    print "hello %(name)s you are %(age)s years old" % locals()

어디에 사촌을 사용합니다.

def example2(obj):
    print "The file at %(path)s has %(length)s bytes" % obj.__dict__

생산 된 튜플을 생성하는 변수를 계산하고 튜플 내에서 % s 일치 위치를 필요가 없습니다.

당신은 그것을 좋아합니까? 사용 / 사용 하시겠습니까? 예 / 아니요, 설명 해주세요.


특히 vars@ kaizer.se에서 언급 한 개선 사항과 @RedGlyph에서 .format한 버전 의 경우 작은 응용 프로그램과 "일회성" 에 적합합니다.

그러나 유지 관리 수명이 긴 국어 응용 프로그램과 많은 유지 관리자의 경우 관행은 유지 관리 문제로 이어질 수 있습니다 @ S.Lott의 대답이 나온 이유라고 생각합니다. 특허 응용 프로그램 (또는 야수를위한 가능성이있는 구성 요소)을 개발하고 유지 관리하는 데있어 상처가없는 사람에게는 제거 할 수 없습니다.

당신이 있다면, 그것은 다음과 같은 몇 가지 형태가 될 것입니다, 또는-에 "심각한"응용 프로그램, 당신은 당신의 형식이 하드 코딩하지 갑자기 _('Hello {name}.')(가), _에서 온다 gettext에 또는 i18n / L10n 프레임 워크 . 요점은 현대적인 응용 프로그램 (또는 사용 가능한 응용 프로그램에서 수있는 가능한 모듈)이 국제화 (AKA i18n) 및 위치 지정 (AKA L10n)을 지원해야한다는 것입니다. 응용 프로그램이 특정 상황에서 "Hello Paul"이 있기 때문에 원합니다. 국가와 문화, 일부에서는 "Hola Paul", 다른 일부에서는 "Ciao Paul"등이 있습니다. 따라서 일상적인 형식은 현재 현지화 설정에 따라 실행시 자동으로 대체됩니다. 하드 코딩되는 대신 데이터베이스에 있습니다. 모든 의도와 목적을 위해 형식 숭배가 항상 리터럴이 아니라 변수라고 상상해보세요.

그래서, 당신이 가진 존재 자체가

formatstring.format(**locals())

당신은 하찮게 정확히 확인할 수 없습니다 어떤 포맷이 사용하게 될 것입니다 지방의 이름. L10N 데이터베이스를 사용하고 정독하고 여기에서 다른 설정에서 사용할 형식을 사용하고 모두 확인해야합니다.

따라서 실제로 어떤 지역 이름이 사용 될지 알지 못합니다 . 이 함수의 유지를 끔찍하게 방해합니다. 언어, 로케일 및 기본 설정의 일부 모호한 조합으로 사용자의 사용자 경험을 끔찍하게 망칠 수 있으므로 지역 변수의 이름을 바꾸거나 제거하지 않습니다.

통합 / 회귀 테스트가 훌륭 리지 베타 릴리스 전에 잡히지 만 QA는 비명을 지르고 릴리스가 지연 될 것입니다 ... 그리고 솔직히 말해서 단위 테스트로 100 % 커버를 목표로 합니다. 합리적입니다. 일단 설정의 조합 폭증 [[L10N 및 더 많은 이유]]과 모든 해당 지원되는 버전을 고려하면 통합 테스트 가 아닙니다 . 따라서 "QA에 걸리기 때문에"(그렇게하면 대형 앱이나 서비스 가능한 구성 요소를 개발할 필요가 없어 오래 지속되지 않을 수 있습니다 .-) 손상 위험을 감수 할 필요가 없습니다.

"Welcome, Dread Overlord!"로 전환 했음에도 불구하고 "name"지역 변수를 제거하지 않을 것입니다. (적절하게 L10n'ed 버전). 당신이 갔기 때문에 locals()...

따라서 코드를 유지하고 편집하는 방식으로 능력을 강화하고 있습니다. 그리고 아마도 그 "이름"지역 변수는 DB 등에서 가져 왔기 때문에 존재하기 때문에 유지 (또는 다른 지역) 주변은 단지 엉망인 성능도 개선되었습니다. 의 표면 편리 locals()가치가 -?)

그러나 잠깐, 더 나쁜 것이 있습니다! lint(예 : pylint )이 할 수 있는 많은 유용한 서비스 중 사용하지 않는 지역 변수에 대해 경고하는 것입니다 (사용하지 않는 전역 변수에 그렇게 할 수 있기 때문에 바라지 만 가능한 구성 요소의 경우에는 약간 너무 힘들다 ;-). 당신과 같은 추론 가끔 맞춤법 오류를 잡을 겁니다이 방법 if ...: nmae = ...보다는 단위 테스트 휴식을보고하고 알아 형사 작업을 수행하여 매우 신속하고 저렴한 비용을 이유 가 파산은 (는 않습니다 강박, 보급 단위 테스트가 을 구석으로 , 결국이 잡을를 맞습니까 ?-)-lint는 사용하지 않는 지역 변수에 대해 알려주고 nmae즉시 수정합니다.

그러나 코드에 blah.format(**locals())가 있거나 동등하게 blah % locals()... 당신은 SOL, 친구입니다 -!) nmae실제로 사용하지 않는 변수인지 아니면 실제로 외부 함수 또는 전달 locals()하는 방법 ? (결국 경고를 무시하거나 무시하는 "울프"효과를 유발 함) 경고하지 않을 것입니다 (동일한 효과 : 경고 없음 ;-). .

"명시적인 것이 암시적인 것보다 낫다"를 비교하십시오. :

blah.format(name=name)

거기에-유지 보수, 성능 및 am-I-hampering-lint 걱정이 더 이상 적용되지 않습니다. 다시없는 기쁨! 당신은 관련된 모든 사람들에게 (보풀 포함 ;-) 정확히 어떤 지역 변수가 사용되고 있는지, 어떤 목적으로 정확히 사용 되는지 를 즉시 분명히 합니다.

계속할 수는있을 것이라고 게시물은 이미 꽤 길다고 생각합니다 .-).

그래서 요약하면 : " γνῶθι σεαυτόν !" 흠, 내 말은 "너 자신을 알아라!" 그리고 "자신"이란 실제로 "코드의 목적과 범위"를 의미합니다. 일회성 또는 거의없는 것이라면 i18n 및 L10n'd가 될 수 있습니다. 유지 관리가 거의 필요하지 않습니다 locals(). 작지만 깔끔한 편리함; 달리 알고 확실하지 않은 경우에도주의를 기울이고 더 명확하게 작업을 수행하십시오. 진행중인 내용을 정확히 입력해야하는 작은 불편 함을 누리고 그에 따른 모든 이점을 누리십시오.

BTW, 이것은 단지 파이썬은 모두 "일회성이, 어쩌면 대화 형 탐색 작은"허용하고 잘 넘어 확장 위험 편의를 지원하여 (프로그래밍 지원하기 위해 노력하고있는 사례 중 하나입니다 locals()- 생각 import *, eval, exec, 및 기타 여러 편의를 위해 네임 스페이스를 정리하고 유지 보수에 머무르는 영향을 위험하게 만들 수 방법)뿐만 아니라 "대형, 가능성이있는"앱 및 구성 요소. 두 가지 모두에서 꽤 좋은 일을 할 수 있습니다. "자신을 알고 싶다" "편리함"부분을 사용하지 않는 경우에만 가능합니다. 단, 실제로 감당할 수 있다고 확신하는 경우는 예외입니다. 대부분의 경우 주요 고려 사항은 "이 작업이 내 네임 스페이스에 어떤 영향을 미치는지, 그리고 컴파일러, lint & c,

"스페이스는 멋진 아이디어 중 하나입니다. 더 많은 작업을 수행해 보겠습니다!" Zen of Python이 결론을 내리는 방법입니다. 그러나 "성인 동의를위한 언어"인 Python을 사용 하면하면 개발 환경, 대상 및 관행의 결과로 의미하는 바의 경계 정의 할 수 있습니다 . 이 힘을 책임감있게 사용하십시오!-)


그러므로 훌륭한 패턴이라고 생각합니다. 나는 개인적으로 그것이 적이라고 생각합니다.

필요한 것이없는 코드는 작성하지 않습니다. 약간 코드가 더 많은 코드보다 낫습니다. locals()예를 들어 있지만 사용 방법을 사용 하면 코드를 사용하고 이해합니다.


백만 년 동안 결코. 형식화의 컨텍스트가 무엇인지 명확하지 않습니다 locals. 거의 모든 변수를 포함 할 수 있습니다. self.__dict__모호하지 않습니다. 미래의 개발자가 로컬과 로컬이 아닌 것에 대해 머리를 긁적 거리게하는 것은 정말 끔찍합니다.

의도적 인 미스터리입니다. 왜 그런 미래의 유지 관리 문제로 인해 조직에 안장을 줍니까?


"사촌"에 관해서는 대신 obj.__dict__새로운 문자열 형식을 사용하면 훨씬 더 좋아 보입니다.

def example2(obj):
    print "The file at {o.path} has {o.length} bytes".format(o=obj)

나는 이것을 repr 방법에 많이 사용합니다.

def __repr__(self):
    return "{s.time}/{s.place}/{s.warning}".format(s=self)

"%(name)s" % <dictionary>또는, 더 나은 "{name}".format(<parameters>)의 장점을 가지고

  • "% 0s"보다 읽기 쉽습니다.
  • 인수 순서와 무관
  • 문자열의 모든 인수를 사용하도록 강요하지 않음

필자는 str.format ()을 선호하는 경향이 있는데, 왜냐하면 파이썬 3 ( PEP 3101에 따라 ) 에서 그렇게하는 방법이어야 하고 이미 2.6에서 사용할 수 있기 때문입니다. locals()하지만,이 작업을 수행해야합니다 :

print("hello {name} you are {age} years old".format(**locals()))

내장 vars([object])( documentation )을 사용하면 두 번째 기능이 더 좋아 보일 수 있습니다.

def example2(obj):
    print "The file at %(path)s has %(length)s bytes" % vars(obj)

물론 효과는 동일합니다.


이제 Python 3.6.0부터이를위한 공식적인 방법이 있습니다 : 형식화 된 문자열 리터럴 .

다음과 같이 작동합니다.

f'normal string text {local_variable_name}'

예를 들면 다음과 같습니다.

"hello %(name)s you are %(age)s years old" % locals()
"hello {name} you are {age} years old".format(**locals())
"hello {} you are {} years old".format(name, age)

그냥 이렇게 :

f"hello {name} you are {age} years old"

다음은 공식적인 예입니다.

>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"  # nested fields
'result:      12.35'

참고:

참고 URL : https://stackoverflow.com/questions/1550479/python-is-using-vars-locals-a-good-practice

반응형