天天看點

Python AttributeError: 'module' object has no attribute xxxx

原因:

  導緻在這個問題的原因是你的子產品名和你要引用的類或方法或變量的名字重了。說通俗點就是,python腳本名字(子產品名)和你要引用的内容(子產品内的類,變量等)的名字重複了,導緻你原本“類->屬性/方法”的引用意圖被解析為了"子產品->屬性”的引用意圖。當子產品下面沒有這個屬性,就抛出了這個錯誤。解決辦法是換不重複的命名。

事故:

市民小py最近在學scrapy。小py覺得對于有程式設計語言基礎的人來說,不存在入不入門的問題,就是剛,坑踩多了就會了(這flag立的...)。是以盡管沒學過python,小py還是直接上了, 然後就遇到了各種奇怪的問題了。下面請看本台記者帶來的問題報導:

我小py在GetOnePara.py檔案中定義了一個提供靜态方法的類GetOnePara:

class GetOnePara():
	@staticmethod
	def getReqUrlDic():
		return xxx
           

然後在爬蟲代碼開頭使用下列代碼引入了該類,希望能在爬蟲中調用該類的靜态方法。

import GetOnePara
class GetOneSp(scrapy.Spider):
	urlDic = GetOnePara.getReqUrlDic() 
           

當小py運作代碼引用的時候發現

urlDic = GetOnePara.getReqUrlDic() 
           

這一行報錯:AttributeError: 'module' object has no attribute 'getReqUrlDic', 翻譯過來是"子產品"對象沒有getReqUrlDic這個參數。

這裡小py犯了兩個錯誤最終導緻了問題:

1.子產品名和類名重複,為混淆提供了可能

2.小py沒有理清import xxx和 from import xxx的差別

什麼是子產品?

簡單地說,子產品就是一個儲存了Python代碼的檔案。子產品也是Python對象,具有随機的名字屬性用來綁定或引用。

(摘自:http://www.runoob.com/python/python-modules.html)。、

import yyy 和 from yyy import xxx的差別?

import yyy是引入yyy這個子產品,沒有指定命名空間,當你使用yyy子產品下的xxx你需要指定命名空間(yyy. xxx的形式),否則無法識别

from yyy import xxx 是從yyy這個子產品引入xxx這個内容,使用xxx的時候就直接寫xxx就行了。(然而并不推薦這種用法)

我們在python裡面import xxx,這個xxx就對應一個xxx.py檔案。 因為子產品也是python對象,是以

小py原本的意圖是通過子產品下的GetOnePara類引用其靜态方法getReqUrlDic。但是

GetOnePara.getReqUrlDic()
           

這句就被解析為在子產品 GetOnePara裡面找直屬的getReqUrlDic屬性(沒有這個屬性),是以報錯了。

根本杜絕問題的方法是確定子產品名(即檔案名)不和子產品内要引用的内容重複。這裡把GetOnePara.py重命名為fGetOnePara.py以區分子產品和子產品内的類。此外還需要 修改GetOnePara的類調用代碼, 為其指定命名空間(其所屬的子產品名),即:

import GetOnePara
urlDic = GetOnePara.getReqUrlDic() #子產品名和類名重合,加上未指定明明空間,導緻解析的結果和實際意圖不服
           

改為 (子產品名.類名.屬性名 的形式)

import fGetOnePara #修改了子產品名
urlDic = fGetOnePara.GetOnePara.getReqUrl() #指定命名空間