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

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

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

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

守著星空守著你 2019-12-18 18:13:57
如何指定方法的返回類型與類本身相同?我在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)為這實際上是一個PyCharm問題。它實際上使用警告和代碼完成中的信息。但是,如果我錯了,需要使用其他語法來糾正我。
查看完整描述

3 回答

?
精慕HU

TA貢獻(xiàn)1845條經(jīng)驗 獲得超8個贊

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

我想你有個例外:

NameError: name 'Position' is not defined

這是因為Position除非使用Python 4,否則必須在注釋中使用它之前定義它。

Python 3.7+:from __future__ import annotations

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

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

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

Python<3.7:使用字符串

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

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

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

來源

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

正向參考

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

這種情況通常發(fā)生在容器類的定義上,其中定義的類發(fā)生在某些方法的簽名中。例如,以下代碼(簡單二叉樹實現(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)該包含一個有效的Python表達(dá)式(即編譯(LIT,‘val’)應(yīng)該是一個有效的代碼對象),并且一旦模塊被完全加載,它應(yīng)該在沒有錯誤的情況下進(jìn)行計算。計算它的本地和全局命名空間應(yīng)該是相同的名稱空間,其中將計算相同函數(shù)的默認(rèn)參數(shù)。

和PEP 563:

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

...

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

from __future__ import annotations

你可能會被誘惑去做的事情

A.定義假人Position

在類定義之前,放置一個虛擬定義:

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ù),并編寫一個修飾器來對類定義進(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而且它會起作用的。



查看完整回答
反對 回復(fù) 2019-12-19
?
胡說叔叔

TA貢獻(xiàn)1804條經(jīng)驗 獲得超8個贊

將類型指定為String是可以的,但總是會讓我感到有些煩躁,因為我們基本上是在繞過解析器。所以你最好不要拼錯這些文字字符串中的任何一個:

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

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

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-12-19
  • 3 回答
  • 0 關(guān)注
  • 380 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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