Python : "with"를 사용하여 즉시 새로운 기능 정의
-
18-09-2019 - |
문제
다음 코드를 변환하고 싶습니다.
...
urls = [many urls]
links = []
funcs = []
for url in urls:
func = getFunc(url, links)
funcs.append(func)
...
def getFunc(url, links):
def func():
page = open(url)
link = searchForLink(page)
links.append(link)
return func
훨씬 더 편리한 코드로 :
urls = [many urls]
links = []
funcs = []
for url in urls:
<STATEMENT>(funcs):
page = open(url)
link = searchForLink(page)
links.append(link)
나는 이것과 함께 이것을하기를 바랐다 with
성명. 내가 벨로우를 언급했듯이, 나는 달성하기를 바랐다.
def __enter__():
def func():
..code in the for loop..
def __exit__():
funcs.append(func)
물론 이것은 작동하지 않습니다.
목록 이해력은 사례에 좋지 않습니다. searchForLink
하나의 기능이 아니라 많은 기능입니다. 읽을 수없는 코드로 바뀔 것입니다. 예를 들어, 이것은 목록 이해에 문제가 있습니다.
for url in urls:
page = open(url)
link1 = searchForLink(page)
link2 = searchForLink(page)
actionOnLink(link1)
actionOnLink(link2)
.... many more of these actions...
links.append(link1)
해결책
약간의 독창적이지만 데코레이터가 func를 등록하고 루프 변수를 기본 인수로 바인딩 할 수 있습니다.
urls = [many urls]
links = []
funcs = []
for url in urls:
@funcs.append
def func(url=url):
page = open(url)
link = searchForLink(page)
links.append(link)
다른 팁
사용하는 것은 의미가 없습니다 with
여기. 대신 목록 이해력을 사용하십시오.
funcs = [getFunc(url, links) for url in urls]
함수를 만드는 방법에는 두 가지가 있습니다. def
그리고 lambda
. Lambdas는 작은 기능을위한 것이므로 귀하의 경우에는 적합하지 않을 수 있습니다. 그러나, 당신이 정말로 원한다면, 당신은 서로 안에 두 개의 람다를 동봉 할 수 있습니다.
urls = [many urls]
links = []
funcs = [(lambda x:
lambda:
links.append(searchForLink(open(x))))(u)
for u in urls]
내 취향에 대해 약간 거치합니다.
줄을 잃습니다 <STATEMENT>(funcs):
편집하다:
내 말은 : 왜 이렇게 하시겠습니까? 각 페이지에 새 기능을 정의하는 이유는 무엇입니까? 왜 그렇게하지 않습니까?
urls = [many urls]
links = []
for url in urls:
page = open(url)
link = searchForLink(page)
links.append(link)
당신은 이것을하기 위해 "와 함께"사용해서는 안됩니다 (파이썬이라면 기괴한 부작용과 파이썬의 역학을 사용하여 거의 확실하게 할 수 있습니다).
Python에서 "With"의 목적은 문서에 설명 된대로, "컨텍스트 관리자가 정의한 메소드로 블록의 실행을 래핑하려면 일반적인 시도를 제외하고는 일반적인 시도가 가능합니다."
나는 당신이 Python의 "와"를 혼란스럽게 생각합니다. 자바 스크립트/VisualBasic "With"는 미용 적으로 유사하지만 효과적으로 관련이 없습니다.
좋은 늙었습니다 Itertools.
from itertools import imap
links.extend(imap(searchForLink, imap(open, urls)))
비록 당신이 선호 할 수도 있습니다 기능의.
from functional import *
funcs = [partial(compose(compose(links.append, searchForLink), open), url) for url in urls]
for func in funcs: func()
수업을 만드는 것이 가치가 없다고 생각합니다. with
사용 : 더 많은 작업을 만들 수 있습니다 __enter__
그리고 __exit__
헬퍼 기능을 작성하는 것보다.
발전기를 사용하여 지연된 계산을 달성하는 것이 좋습니다.
def MakeLinks(urls):
for url in urls:
page = open(url)
link = searchForLink(page)
yield link
links = MakeLinks(urls)
링크를 원할 때 :
for link in links:
print link
URL은이 루프 중에 찾아 오르고 한 번에 모두가 아닙니다 (피하기 위해 트링하는 것처럼 보입니다).