1

Djangoプロジェクト用の基本的なPythonクラスサブクラスシステムを開発していますが、奇妙な問題が発生しています。

まず第一に、クラスの定義:

ファイルclasses.py

class BaseAd(object):
    """ base class for all the ads, with common parameters """

    def __init__(self, dom, web, loc, cc, a, c, date, desc, hl, **kwargs):
        self.domain = self.doDomain(dom)
        self.url = self.doUrl(web)
        self.description = self.doDescription(desc, hl)
        self.location = self.doLocation(a, c, loc)
        self.date = self.doDate(date)

ファイルjobs.py

class JobAd(BaseAd):
    """ extends BaseAd with more parameters """

    def __init__(self, domain, url, location, countrycode, area, city, 
                 index_date, description, 
                 contract_multivalue, salary_min, company, job_title, **kwargs):

        self.contract_type = self.doContract(contract_multivalue)
        self.salary = self.doSalary(salary_min)
        self.company = self.doCompany(company)
        self.title = self.doTitle(job_title)

        """ Super constructor call """
        super(JobAd, self).__init__(
            domain,
            url,
            location,
            countrycode,
            area,
            city,
            index_date,
            description,
            **kwargs
        )

どちらのクラスにもそれぞれのメソッド(doDomain、doSalaryなど)がありますが、入力として取得した文字列を返すだけなので、現在は関係ありません(将来的にはより適切に実装されるため、現在は必要ありません)。kwargsは、役に立たないが、元のdictの返されるパラメータを格納するために使用されます(そうでない場合はエラーが発生します)

JobAdクラスは、PythonからSolrへのインターフェースsunburntのコンストラクターパラメーターとして使用されます。クラスを定義してメソッドに渡すと、solr応答(単なるdict)で定義されたフィールドがクラスに変換されます。したがって、JobAdのinitで定義されたパラメーターは、solrスキーマでの定義と同じ名前である必要があります。

これは実際のコンストラクター呼び出しです。

/path/to/myapp/resultsets/views_json.py in job_search_json
        #lines splitted for better reading
        #res is a solr search object

        items = res.paginate(start=start, rows=res_per_page)
        .sort_by("-index_date")
        .sort_by("-score")
        .sort_by("-md5")
        .sort_by("-posted_date")
        .execute(constructor=JobAd)

次のスタックトレースには次のものがあります。

/path/to/sunburnt-0.6-py2.7.egg/sunburnt/search.py in execute

        return self.transform_result(result, constructor)

    ...

▼ Local vars
Variable         Value
self             sunburnt.search.SolrSearch object at 0x7f8136e78450
result           sunburnt.schema.SolrResponse object at 0x7f8136e783d0
constructor      class 'myapp.models.jobs.JobAd'

そして最後に

/path/to/sunburnt-0.6-py2.7.egg/sunburnt/search.py in transform_result

            result.result.docs = [constructor(**d) for d in result.result.docs]

最後の「ローカル変数」タブ内には、結果ディクショナリがあります(構造のみであり、値を含む完全な辞書ではありません)。

self    sunburnt.search.SolrSearch object at 0x7f8136e78450
d      {'area': 
        'city': 
        'contract_multivalue': 
        'country': 
        'countrycode': 
        'currency': 
        'description': 
        'district': 
        'domain': 
        'fileName': 
        'index_date':
        'job_experience':
        'job_field_multivalue':
        'job_position_multivalue': 
        'job_title':
        'job_title_fac':
        'latitude': 
        'location': 
        'longitude': 
        'md5':
        'salary_max': 
        'salary_min': 
        'study':
        'url':
        'urlPage':
        }

constructor    class 'tothego_frontend.sito_maynard.models.jobs.JobAd'

django.logファイルには、DogSlowトラップがトラップされた行以外のことを通知しないことを除いて、他のエラーはありません。

これは私が得ているエラーです:

TypeError at /jobs/us/search/

__init__() takes exactly 13 arguments (12 given)

私が期待している動作は、実際に発生している動作ではありません。クラスに親のコンストラクター(10個の引数)を呼び出させる代わりに、独自のinit(14個の引数)を使用しています。

私は古いPythonクラス定義も試してきました。スーパークラスに「オブジェクト」はありません。サブクラスのinit内では、親クラスはBaseAdとして初期化されます。init(self、...); また、サブクラスのinit(a la java)内の最初のステートメントとしてスーパーメソッドを呼び出そうとしていますが、何も変わっていないようです。

私はここで何が間違っているのですか?

編集:2番目の初期化行の長さを修正しましたが、少し多すぎました!

質問されたDJANGOのスタックトレースからの追加情報

最新の考え:ドキュメントに何も記載されていなくても、sunburntはクラスの継承をサポートしていないと思い始めています。

新しい編集:今日のいくつかのテストの後、これは私が発見したものです(これまでのところ)

  • 日焼けは継承を可能にします
  • 3つのパラメーターが同期していないため、コードとエラーが更新されました

今では常に議論が欠けています。「自己」かも?もうどこを見ればよいのか本当にわかりません。エラーは以前と同じです(同じスタックトレース)が、間違ったパラメーターが異なるだけです。

実際に問題を見つけました。initパラメーターにいくつかのデフォルト値を追加することで、実際のエラー、つまり入力にフィールドがないことを見つけることができました。時間を無駄にしてごめんなさい、カウンセリングありがとうございます

4

1 に答える 1

1

私はあなたのコードを取り ( sdo*からメソッドを削除__init__)、より単純な例に変えて、あなたが述べたように問題を再現しようとしました。

class BaseAd(object):
    """ base class for all the ads, with common parameters """

    def __init__(self, dom, web, loc, cc, a, c, date, desc, hl, **kwargs):
        self.domain = dom
        self.url = web
        self.description = desc
        self.location = loc
        self.date = date

class JobAd(BaseAd):
    """ extends BaseAd with more parameters """

    def __init__(self, domain, url, location, countrycode, area, city, 
                 index_date, description, solr_highlights, 
                 contract_type, salary, company, job_title, **kwargs):

        self.contract_type = contract_type
        self.salary = salary
        self.company = company
        self.title = job_title

        """ Super constructor call """
        super(JobAd, self).__init__(
            domain,
            url,
            location,
            countrycode,
            area,
            city,
            index_date,
            description,
            solr_highlights,
            **kwargs
        )

j = JobAd(1,2,3,4,5,6,7,8,9,10,11,12,13,kwarg1="foo",kwarg2="bar")

Python 2.7.2 を実行している場合、これはエラーなしで正常に実行されます。__init__おそらく、エラーで参照されているのはs init が実際に14個の引数を持っているJobAdため、スーパーではなくJobAd、エラーが不平を言っていることを示唆しています。__init__不十分な数の引数で JobAdd が呼び出されている場所を見つけることをお勧めします。

他の人が言っているように、完全なスタック トレースを投稿し、JobAd がどのように使用されているかを示すことは、根本原因を特定する上で非常に重要です。

于 2012-06-08T16:14:23.887 に答える