Python : 'from X import Y'로 가져온 컴포넌트 Y를 다시로드 하시겠습니까?
Python에서를 사용하여 인터프리터 세션에서 모듈 X를 가져 왔고 모듈 import X
이 외부에서 변경되면 reload(X)
. 그러면 내 통역 세션에서 변경 사항을 사용할 수 있습니다.
을 사용하여 모듈 X에서 구성 요소 Y를 가져올 때도 이것이 가능한지 궁금합니다 from X import Y
.
reload Y
Y는 모듈 자체가 아니라 모듈 내부의 구성 요소 (이 경우 클래스)이므로 문 이 작동하지 않습니다.
인터프리터 세션을 떠나지 않고 (또는 전체 모듈을 가져 오지 않고) 모듈의 개별 구성 요소를 다시로드 할 수 있습니까?
편집하다:
설명을 위해 질문은 모듈 X 에서 클래스 또는 함수 Y 를 가져 와서 패키지 X에서 모듈 Y가 아니라 변경시 다시로드하는 것입니다.
Y는 모듈 (그리고 X 패키지)하면 reload(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
우선 재 장전을 피할 수 있다면 전혀 사용하지 말아야합니다. 하지만 이유가 있다고 가정 해 봅시다 (예 : 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 modulename import func
import sys
reload(sys.modules['modulename'])
from modulename import func
이렇게하려면 다음을 수행하십시오.
from mymodule import myobject
대신 다음을 수행하십시오.
import mymodule
myobject=mymodule.myobject
이제 계획했던 것과 동일한 방식으로 myobject를 사용할 수 있습니다 (모든 곳에서 귀찮은 읽을 수없는 mymodule 참조없이).
대화식으로 작업 중이고 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로 가져온 경우-X를 다시로드하고 모듈을 다시로드하는 것보다 Z를 다시로드해야합니다. 모든 모듈을 다시로드 (예 : using [ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
) 하더라도 Z를 다시로드하기 전에 X를 다시로드 할 수 있습니다. Y 값을 새로 고치지 마십시오.
reload()
모듈X
,reload()
가져 오기 모듈Y
에서X
.
다시로드해도 다른 네임 스페이스에 바인딩 된 이미 생성 된 객체는 변경되지 않습니다 (Alex의 스타일 가이드를 따르더라도).
경우 당신은 jupyter 환경에서 최선을 다하고, 당신은 이미 from module import function
, 마법 기능을 사용할 수 있습니다 autoreload
에 의해
%load_ext autoreload
%autoreload
from module import function
autoreload
in IPython 의 소개는 여기에 있습니다 .
Just to follow up on AlexMartelli's and Catskul's answers, there are some really simple but nasty cases that appear to confound reload
, at least in Python 2.
Suppose I have the following source tree:
- foo
- __init__.py
- bar.py
with the following content:
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)
This works just fine without using reload
:
>>> from foo import Quux
Loading bar
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> Quux()
Quux[2, x=43]
But try to reload and it either has no effect or corrupts things:
>>> 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
The only way I could ensure the bar
submodule was reloaded was to reload(foo.bar)
; the only way I access the reloaded Quux
class is to reach in and grab it from the reloaded sub module; but the foo
module itself kept holding onto the original Quux
class object, presumably because it uses from bar import Bar, Quux
(rather than import bar
followed by Quux = bar.Quux
); furthermore the Quux
class got out of sync with itself, which is just bizarre.
참고URL : https://stackoverflow.com/questions/1739924/python-reload-component-y-imported-with-from-x-import-y
'Programing' 카테고리의 다른 글
size_t와 unsigned int의 차이점은 무엇입니까? (0) | 2020.10.10 |
---|---|
Avro 대 Parquet (0) | 2020.10.10 |
오류로 경고-제거하는 방법 (0) | 2020.10.10 |
먼저 EF 코드의 CTP5에 대해 ProxyCreationEnabled를 끄는 단점은 무엇입니까? (0) | 2020.10.10 |
Hashmap 키의 이름을 바꿀 수 있습니까? (0) | 2020.10.10 |