第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何指定方法的返回類型與類本身相同?

如何指定方法的返回類型與類本身相同?

元芳怎么了 2019-07-25 14:14:23
如何指定方法的返回類型與類本身相同?我在python 3中有以下代碼:class Position:     def __init__(self, x: int, y: int):         self.x = x         self.y = y    def __add__(self, other: Position) -> Position:         return Position(self.x + other.x, self.y + other.y)但是我的編輯器(PyCharm)說,無法解析引用位置(在__add__方法)。如何指定預(yù)期返回類型為Position?編輯:我認(rèn)為這實(shí)際上是一個(gè)PyCharm問題。它實(shí)際上使用警告和代碼完成中的信息。但是,如果我錯(cuò)了,需要使用其他語法來糾正我。
查看完整描述

3 回答

?
慕妹3242003

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超6個(gè)贊

如果您使用的是Python4.0,那么它只是起作用了。從今天(2019年)開始,在3.7+中,您必須使用將來的語句(from __future__ import annotations)-對于Python3.6或更低的版本,請使用字符串。

我想你有個(gè)例外:

NameError: name 'Position' is not defined

這是因?yàn)?/trans>Position除非使用Python 4,否則必須在注釋中使用它之前定義它。

Python 3.7+:from __future__ import annotations

Python 3.7Pep 563:推遲對說明的評價(jià)..使用未來語句的模塊from __future__ import annotations將自動(dòng)將注釋存儲(chǔ)為字符串:

from __future__ import annotationsclass Position:
    def __add__(self, other: Position) -> Position:
        ...

這將成為Python4.0中的默認(rèn)設(shè)置。因?yàn)镻ython仍然是一種動(dòng)態(tài)類型語言,所以在運(yùn)行時(shí)不進(jìn)行類型檢查,所以輸入注釋不應(yīng)該對性能產(chǎn)生影響,對嗎?不對!在python 3.7之前,類型模塊以前是核心中最慢的python模塊之一所以如果你import typing你會(huì)看到業(yè)績提高7倍升級到3.7。

Python<3.7:使用字符串

根據(jù)PEP 484,您應(yīng)該使用字符串而不是類本身:

class Position:
    ...
    def __add__(self, other: 'Position') -> 'Position':
       ...

如果您使用Django框架,這可能很熟悉,因?yàn)镈jango模型也使用字符串進(jìn)行前向引用(外鍵定義,其中外接模型是self或尚未宣布)。這應(yīng)該適用于PyCharm和其他工具。

來源

的相關(guān)部分佩普484佩普563為了省去你的旅行:

正向參考

當(dāng)類型提示包含尚未定義的名稱時(shí),該定義可以表示為字符串文本,待稍后解析。

這種情況通常發(fā)生在容器類的定義上,其中定義的類發(fā)生在某些方法的簽名中。例如,以下代碼(簡單二叉樹實(shí)現(xiàn)的開始)無法工作:

class Tree:
    def __init__(self, left: Tree, right: Tree):
    self.left = left
    self.right = right

為了解決這一問題,我們寫道:

class Tree:
    def __init__(self, left: 'Tree', right: 'Tree'):
        self.left = left
        self.right = right

字符串文字應(yīng)該包含一個(gè)有效的Python表達(dá)式(即編譯(LIT,‘val’)應(yīng)該是一個(gè)有效的代碼對象),并且一旦模塊被完全加載,它應(yīng)該在沒有錯(cuò)誤的情況下進(jìn)行計(jì)算。計(jì)算它的本地和全局命名空間應(yīng)該是相同的名稱空間,其中將計(jì)算相同函數(shù)的默認(rèn)參數(shù)。

和PEP 563:

在Python4.0中,函數(shù)和變量注釋將不再在定義時(shí)計(jì)算。相反,字符串窗體將保留在相應(yīng)的__annotations__字典。靜態(tài)類型檢查器在行為上沒有區(qū)別,而在運(yùn)行時(shí)使用注釋的工具將不得不執(zhí)行延遲的評估。

...

可以使用以下特殊導(dǎo)入從Python3.7開始啟用上面描述的功能:

from __future__ import annotations

你可能會(huì)被誘惑去做的事情

A.定義假人Position

在類定義之前,放置一個(gè)虛擬定義:

class Position(object):
    passclass Position(object):
    ...

這將消除NameError甚至看起來還可以:

>>> Position.__add__.__annotations__{'other': __main__.Position, 'return': __main__.Position}

但是嗎?

>>> for k, v in Position.__add__.__annotations__.items():...     print(k, 'is Position:', v is Position)                                                                                                                                                                                                                  
return is Position: Falseother is Position: False

B.為添加注釋而進(jìn)行的猴子補(bǔ)丁程序:

您可能需要嘗試一些Python元編程魔術(shù),并編寫一個(gè)修飾器來對類定義進(jìn)行猴子修補(bǔ),以便添加注釋:

class Position:
    ...
    def __add__(self, other):
        return self.__class__(self.x + other.x, self.y + other.y)

裝修人員應(yīng)對此負(fù)責(zé):

Position.__add__.__annotations__['return'] = PositionPosition.__add__.__annotations__['other'] = Position

至少這似乎是對的:

>>> for k, v in Position.__add__.__annotations__.items():...     print(k, 'is Position:', v is Position)                                                                                                                                                                                                                  
return is Position: Trueother is Position: True

可能太麻煩了。

結(jié)語

如果使用3.6或更低版本,請使用包含類名的字符串文本,在3.7中使用from __future__ import annotations而且它會(huì)起作用的。



查看完整回答
反對 回復(fù) 2019-07-26
?
不負(fù)相思意

TA貢獻(xiàn)1777條經(jīng)驗(yàn) 獲得超10個(gè)贊

將類型指定為String是可以的,但總是會(huì)讓我感到有些煩躁,因?yàn)槲覀兓旧鲜窃诶@過解析器。所以你最好不要拼錯(cuò)這些文字字符串中的任何一個(gè):

def __add__(self, other: 'Position') -> 'Position':
    return Position(self.x + other.x, self.y + other.y)

一個(gè)細(xì)微的變化是使用綁定的type var,至少在聲明type var時(shí),您必須只寫一次字符串:

from typing import TypeVarT = TypeVar('T', bound='Position')class Position:

    def __init__(self, x: int, y: int):
        self.x = x
        self.y = y    def __add__(self, other: T) -> T:
        return Position(self.x + other.x, self.y + other.y)



查看完整回答
反對 回復(fù) 2019-07-26
  • 3 回答
  • 0 關(guān)注
  • 377 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號