1. ホーム
  2. パイソン

Python AttributeError: 'module' オブジェクトには xxxx という属性がありません。

2022-02-26 01:54:11

原因

<スパン この問題の原因は、モジュール名と、参照しているクラスやメソッド、変数の名前が重複していることです。平たく言うと、pythonスクリプト名(モジュール名)と、参照している内容(モジュール内のクラスや変数など)の名前が重複しているため、元の "class-> property/method" の参照意図が "module-> property" の参照意図に分解されてしまうということです。モジュールの下にそのようなプロパティが存在しない場合、このエラーがスローされます。回避策としては、ネーミングを繰り返さないものに変更することです。


インシデント

<スパン 最近、一般の方がscrapyを学んでいます。 small pyは、プログラミング言語の基礎知識を持っている人にとっては、問題なく始められると思いますが、ただ、もっと踏み込むと(このフラグを立てると...)ピタリといきます。というわけで、pythonを学んだことがない私でも、そのままやってみたら、いろいろと不思議な問題が発生しました。以下、記者による問題の報告です。


I リトルパイは GetOnePara.py という静的メソッドを提供するファイルです。 クラス GetOnePara :

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

そして、このクラスをクローラーコードの冒頭に以下のコードで導入します。うまくいけば、クローラー内でこのクラスの静的メソッドを呼び出すことができます。

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

little py がコードリファレンスを実行すると、次のようになります。

urlDic = GetOnePara.getReqUrlDic() 

この行でエラーが報告されます。AttributeError: 'module' object has no attribute 'getReqUrlDic', which translates to the "module" object does not have the parameter getReqUrlDic.これは、モジュールオブジェクトがパラメータを持たないことを意味します。

ここでリトルパイは、最終的に問題を引き起こす2つのミスを犯しました。

<スパン 1. モジュール名とクラス名が重複しているため、混乱する可能性がある

2. little py は import xxx と from import xxx の違いを理解していない。


モジュールとは何ですか?

<スパン 簡単に言うと、モジュールはPythonのコードを保持するファイルです。 モジュールはPythonのオブジェクトでもあり、バインドやリファレンスのためのランダムな名前属性をもっています。

<スパン (From: http://www.runoob.com/python/python-modules.html)。そして


<スパン import yyyとfrom yyy import xxxの違いは何ですか?

import yyy は yyyy モジュールを導入するもので、名前空間は指定されていません、xxx の下で yyyy モジュールを使用する場合 名前空間を指定する必要があります。 (yyyy.xxxという形式)でないと、認識されません。

from yyy import xxx は yyyy モジュールから xxx の内容を導入するもので、 xxx を使う場合は xxx を直接書けばよい。(ただし、この使い方はあまりお勧めできません。)


python内部でxxxをインポートしており、このxxxがxxx.pyファイルに対応します。モジュールもpythonのオブジェクトなので

little pyの本来の目的は、モジュール下のGetOneParaクラスを通じて、その静的メソッドgetReqUrlDicを参照することでした。 しかし

GetOnePara.getReqUrlDic()

これは、モジュールGetOnePara内の直接的なgetReqUrlDicプロパティ(これは存在しない)を探していると解析されるため、エラーが報告されます。

この問題を全くなくす方法は、モジュール名(=ファイル名)とモジュール内で参照するコンテンツが重複しないようにすることです。モジュールとその中のクラスを区別するために、GetOnePara.pyをfGetOnePara.pyにリネームしてください。また、名前空間(所属するモジュールの名前)を指定するために、GetOneParaクラスの呼び出しコードを修正する必要があります、すなわち。

import GetOnePara
urlDic = GetOnePara.getReqUrlDic() # Module name and class name overlap, plus no explicit space is specified, resulting in parsed results that don't match the actual intent

モジュール名、クラス名、属性名)に変更する。

import fGetOnePara #Modified the module name
urlDic = fGetOnePara.GetOnePara.getReqUrl() # specifies the namespace