2012-01-22 2 views
7

Python에서 상속을 사용하면 재미있는 가져 오기 오류가 발생합니다.Python 하위 모듈을 가져온 부모 모듈을 사용할 수 없습니다.

상위 클래스에서 sqlite3 모듈을 가져옵니다. 하위 클래스에서 sqlite3 함수를 사용하려고했지만 "NameError : 전역 이름 'sqlite3'이 정의되지 않았습니다."라는 오류가 발생합니다. 왜 이런 일이 발생합니까? & 어떻게 수정합니까?

2 개 개의 클래스는 별도의 파일에 있습니다

Parent.py

import sqlite3 

class Parent: 
    def __init__(self): 

     self.create_database() 

    def create_database(self): 
     """ Virtual function to be overriden in child classes """ 
     pass 

    ...more class functions that use sqlite3 functions 

Child.py

import Parent 

class Child(Parent.Parent): 
    def create_database(self): 
     self.db = sqlite3.connect("test.db") # Error occurs HERE 

c = Child() 

답변

12

sqlite3를 모듈이 상위 모듈로 가져 따라서 해당 모듈을 통해 액세스 할 필요가

self.db = Parent.sqlite3.connect("test.db") 

당신이 그렇게 할 파이썬을 알려하지 않는 한 직접 예를

를 들어, 하위 모듈로 가져올 수 없습니다
from Parent import * 

당신이 당신은을 가져 오지 않은

+1

단순히 자식 모듈에서도'import sqlite3'을 사용하십시오. – jsbueno

+1

왜 부모님을 통해 sqlite3에 액세스 하시겠습니까? 또한 "import *"는 그리 좋지 않습니다. –

+1

동의 함,이 것은 받아 들일 수있는 대답이 아닙니다. "import sqlite3"이 올바른 방법입니다. –

5

아이가 자신의 네임 스페이스가 있고 sqlite3를 수입하지 않은 그것으로. 따라서 sqlite3을 Child.py로 가져와야합니다. import Parent.sqlite3을 수행 한 다음 Parent.sqlite3.connect으로 전화 할 수도 있습니다. 모듈을 실제로는 한 번만 가져오고 (첫 번째 가져 오기에서 코드가 도달 할 때) sqlite3을 가져 오는 대신 실제 모듈을 현재 네임 스페이스에 추가하기 만하면 실제 이점이 없습니다.

2

아동 모듈 내에서 상위 모듈의 모든 구성원에 액세스 할 수 있습니다모듈을 Parent 클래스에 추가하면됩니다 (하지만 실제로 이상하게 보일 수 있습니다). Parent 클래스가 포함 된 모듈을 sqlite3Parent.py개로 가져오고 해당 정의에 sqlite3 모듈을 사용합니다.

그런 다음 별도의 모듈이 Parent.py 모듈을 가져오고 Parent의 하위 클래스를 정의합니다. 이것은 Parent 클래스의 모든 것을 자동으로 스코프 [1]에 가져 오지 않으며, 에있는 Parent 클래스를 정의 할 때 스코프에 있던 모든 것을 가져 오지는 않습니다. Parent.py에 다른 클래스를 선언 한 경우 해당 클래스가 상위 클래스와 동일한 모듈에 있었기 때문에 그 이름이 Child 인 것으로 예상되지 않을 것입니다. 그렇다면 왜이 모듈이 Parent 님의 방법 중 일부를 정의 하시겠습니까?

sqlite3을 (를) 가져온 네임 스페이스에 대한 참조가 이미 있습니다. class Child(Parent.Parent)이라고 말하면 하위 클래스로는 Parent 클래스가 있습니다. 그래서 Parent.sqlite3을 사용하여 sqlite3에 액세스 할 수 있습니다.하지만 이는 Python에서 모듈을 사용하는 매우 이상한 방법입니다.

일반적으로 import sqlite3을 (를) Child.py 상단에 추가하는 것이 좋습니다. 그런 다음 코드를 읽는 사용자는 sqlite3을 사용하는 것으로 나타납니다.Parent.py에서 가져온 sqlite3을 사용했다면 정상적인 방법을 사용하지 않은 이유가 궁금 할 것이며 추가 한 코드로 sqlite3 모듈을 래핑하는 것과 같이 까다로운 작업을 수행하고 있다고 생각할 것입니다. 그리고 방금 import * from Parent을 완료했다면, 심지어 명확하지 않습니다. sqlite3이라는 이름이 나오고 독자가 혼란에 빠지게됩니다. 그리고 결국 sqlite3을 가져올 필요가 없다고 결정하면 코드가 이상하게 작동하지 않지만 Parent.py에 결국 표시되지만 오류 메시지는 Parent.py에 대해 알려주지 않습니다.

일반적으로 표준 모듈 가져 오기와 같은 간단한 작업을 수행하는 경우 간단하고 분명한 방법으로 처리해야합니다. 사람들은 그것을 읽는 것에 익숙해 있으며, 멈추고 그것에 대해 생각할 필요없이 정말로 쉽게 받아 들일 것입니다. 문제가 될 가능성이 가장 큰 "혼란스러워하는 독자"는이 코드의 작동 방식을 정확히 잊어 버린 지 몇 달 만에 있습니다. 당신은 당신이 그것을 다시 알아내는 일을 할 때 가능한 한 쉽게 그것을 만들고 싶습니다.


[1] 부모 클래스에서 상속하는 범위,과는 전혀 무관 즉 당신이 그들을 자격없이 액세스 할 수 있습니다 이름. 자식 클래스를 정의하는 클래스 블록 내에 부모 클래스의 메서드와 클래스 변수 에 액세스하지 못합니다.. 이것이 의미하는 바는 자식 클래스가 생성 된 후에 인스턴스와 클래스 변수에 대한 이름 해석 프로토콜이 자식 클래스에서 사물을 찾지 못하면 부모를 보게된다는 것입니다. 이것은 다소 미묘한 점으로, 기본적으로 자식 클래스 블록 (메서드의 정의 포함) 내에서 (1) 오류가 발생하지만 (2) 자식 클래스가 존재하면 (메서드가 실제로 실행될 때 포함)) Child.some_parent_method() (또는 메서드 내에서 self.some_parent_method()) 부모 메서드를 찾습니다.

관련 문제