파이썬: 'from X import Y'로 가져온 구성 요소 Y를 다시 로드하시겠습니까?
파이썬에서 인터프리터 세션에서 모듈 X를 가져오면 다음을 사용하여import X
, 외부에서 모듈이 변경되면 모듈을 다시 로드할 수 있습니다.reload(X)
. 그러면 제 통역 세션에서 변경 내용을 확인할 수 있습니다.
모듈 X에서 부품 Y를 가져올 때도 이것이 가능한지 궁금합니다.from X import Y
.
성명서reload Y
Y는 모듈 자체가 아니라 모듈 내부의 구성 요소(이 경우 클래스)이기 때문에 작동하지 않습니다.
인터프리터 세션을 떠나지 않고(또는 모듈 전체를 가져오는) 모듈의 개별 구성 요소를 다시 로드할 수 있습니까?
편집:
명확하게 설명하기 위해, 문제는 패키지 X에서 모듈 Y가 아닌 모듈 X에서 클래스 또는 함수 Y를 가져오고 변경 시 다시 로드하는 것입니다.
정답.
내 시험에서, 표시된 답은 단순한 것을 암시합니다.reload(X)
, 작동하지 않습니다.
정확한 대답은 다음과 같습니다.
from importlib import reload # python 2.7 does not require this
import X
reload( X )
from X import Y
시험
제 시험은 다음과 같습니다(Python 2.6.5 + bpython 0.9.5.2).
X.py :
def Y():
print "Test 1"
bpython:
>>> from X import Y
>>> print Y()
Test 1
>>> # Edit X.py to say "Test 2"
>>> print Y()
Test 1
>>> reload( X ) # doesn't work because X not imported yet
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'X' is not defined
>>> import X
>>> print Y()
Test 1
>>> print X.Y()
Test 1
>>> reload( X ) # No effect on previous "from" statements
>>> print Y()
Test 1
>>> print X.Y() # first one that indicates refresh
Test 2
>>> from X import Y
>>> print Y()
Test 2
>>> # Finally get what we were after
Y가 모듈이고 X가 패키지인 경우reload(Y)
그렇지 않으면 좋은 Python 스타일 가이드(예: 제 고용주)가 모듈 외에는 어떤 것도 가져오지 말라고 말하는 이유를 알게 될 것입니다. (이것은 여러 가지 훌륭한 이유 중 하나이지만, 사람들은 아무리 좋은 생각이 아니라고 설명해도 여전히 기능과 클래스를 직접 가져옵니다;-).
from modulename import func
import importlib, sys
importlib.reload(sys.modules['modulename'])
from modulename import func
일단, 만약 피할 수 있다면, 재장전을 전혀 사용하지 말아야 합니다.하지만 여러분의 이유(즉, IDLE 내부 디버깅)가 있다고 가정해 보겠습니다.
라이브러리를 다시 로드해도 이름이 모듈의 네임스페이스로 다시 연결되지 않습니다.이렇게 하려면 변수만 다시 할당하면 됩니다.
f = open('zoo.py', 'w')
f.write("snakes = ['viper','anaconda']\n")
f.close()
from zoo import snakes
print snakes
f = open('zoo.py', 'w')
f.write("snakes = ['black-adder','boa constrictor']\n")
f.close()
import zoo
reload(zoo)
snakes = zoo.snakes # the variable 'snakes' is now reloaded
print snakes
몇 가지 다른 방법으로 할 수 있습니다.로컬 네임스페이스를 검색하고 문제가 된 모듈에서 가져온 모든 것을 재할당하여 프로세스를 자동화할 수 있지만, 우리는 충분히 악의적이라고 생각합니다.
만약 당신이 목성 환경에서 일을 하고 있다면, 당신은 이미from module import function
마법의 기능을 사용할 수 있고,autoreload
타고
%load_ext autoreload
%autoreload
from module import function
도입부.autoreload
아이피톤은 여기에 주어집니다.
이 작업을 수행하려면:
from mymodule import myobject
대신 이렇게 하십시오.
import mymodule
myobject=mymodule.myobject
이제 내 개체를 계획했던 것과 동일한 방식으로 사용할 수 있습니다(모든 곳에서 읽을 수 없는 내 모듈 참조 없이).
대화형 작업을 하고 있고 내 모듈에서 내 개체를 다시 로드하려면 이제 다음을 사용할 수 있습니다.
reload(mymodule)
myobject=mymodule.myobject
당신이 사용했다고 가정할 때from X import Y
, 다음 두 가지 옵션이 있습니다.
reload(sys.modules['X'])
reload(sys.modules[__name__]) # or explicitly name your module
아니면
Y=reload(sys.modules['X']).Y
몇 가지 고려 사항:
A. 가져오기 범위가 모듈 전체가 아닌 경우(예: 함수로 가져오기) - 두 번째 버전을 사용해야 합니다.
에서 로 가져온 - 로드하고 로드하고 로드하는 B ). Y를 다른 모듈(Z)에서 X로 가져온 경우 - Z를 다시 로드하고 X를 다시 로드하고 모듈을 다시 로드하고 모든 모듈을 다시 로드하는 경우(예: 사용)[ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
하기 전에 로드할 수 의 값을 고치지 Z 를 에 X 를 Y 를 합니다.
reload()
eX
,reload()
gY
X
.
다시 로드해도 이미 생성된 다른 네임스페이스에 바인딩된 개체는 변경되지 않습니다(알렉스의 스타일 가이드를 따르더라도).
알렉스 마르텔리와 캣츠쿨의 답변을 따라가기 위해, 혼동되는 것처럼 보이는 정말 간단하지만 고약한 사례들이 있습니다.reload
2 에서는.
다음과 같은 소스 트리가 있다고 가정합니다.
- foo
- __init__.py
- bar.py
다음의 내용을 포함하여:
init.py :
from bar import Bar, Quux
bar.py :
print "Loading bar"
class Bar(object):
@property
def x(self):
return 42
class Quux(Bar):
object_count = 0
def __init__(self):
self.count = self.object_count
self.__class__.object_count += 1
@property
def x(self):
return super(Quux,self).x + 1
def __repr__(self):
return 'Quux[%d, x=%d]' % (self.count, self.x)
은 합니다를 잘 합니다.reload
:
>>> from foo import Quux
Loading bar
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> Quux()
Quux[2, x=43]
하지만 재장전을 시도해도 아무런 효과가 없거나 물건을 손상시킵니다.
>>> import foo
Loading bar
>>> from foo import Quux
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> reload(foo)
<module 'foo' from 'foo\__init__.pyc'>
>>> Quux()
Quux[2, x=43]
>>> from foo import Quux
>>> Quux()
Quux[3, x=43]
>>> reload(foo.bar)
Loading bar
<module 'foo.bar' from 'foo\bar.pyc'>
>>> Quux()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo\bar.py", line 17, in __repr__
return 'Quux[%d, x=%d]' % (self.count, self.x)
File "foo\bar.py", line 15, in x
return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> Quux().count
5
>>> Quux().count
6
>>> Quux = foo.bar.Quux
>>> Quux()
Quux[0, x=43]
>>> foo.Quux()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo\bar.py", line 17, in __repr__
return 'Quux[%d, x=%d]' % (self.count, self.x)
File "foo\bar.py", line 15, in x
return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> foo.Quux().count
8
할 수 bar
되었습니다.reload(foo.bar)
; 내가 재장전된 것에 접근할 수 있는 유일한 방법.Quux
이지만,foo
다를 있었습니다.Quux
체,입니다를 일 것입니다.from bar import Bar, Quux
아닌import bar
를 이어dQuux = bar.Quux
나아가 );Quux
수업이 자기 자신과 맞지 않게 된 것은 이상한 일입니다.
언급URL : https://stackoverflow.com/questions/1739924/python-reload-component-y-imported-with-from-x-import-y
'source' 카테고리의 다른 글
선택한 드롭다운 목록에서 메타박스 데이터 저장 (0) | 2023.09.23 |
---|---|
카트 에이잭스와 미니카트에 우커머스 추가 (0) | 2023.09.23 |
WooCommerce 내 JetPack의 댓글 구독 상자 위치 변경 (0) | 2023.09.23 |
주문한 목록이 CSS로 1.1, 1.2, 1.3(단, 1, 2, 3, ...)과 같은 결과를 낼 수 있습니까? (0) | 2023.09.23 |
PHP에서 INET_ATON()과 INET_NTOA()? (0) | 2023.09.23 |