日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python变量类型怎么决定的_Python数据类型提示痛点的解决方案探讨

發(fā)布時間:2023/12/4 python 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python变量类型怎么决定的_Python数据类型提示痛点的解决方案探讨 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

幾個月前,你寫了一段Python代碼,當時只有你和上帝能看懂。幾個月后,這段代碼就只有上帝能看懂了。

痛點是什么

Python是一門弱類型的動態(tài)語言,在看其他人寫的一些Python項目的代碼、特別是大型項目的代碼的時候,是不是會有這樣的體驗:很多函數(shù)的參數(shù)超多,而且很難看出來每個參數(shù)代表什么含義、是什么數(shù)據(jù)類型的、字典類型的參數(shù)究竟可以傳哪些參數(shù)等等等。如果寫這些代碼的人習慣還不好,沒有寫什么注釋或注釋寫的比較糟糕,那看這種代碼簡直就是一種折磨了,這樣的情況下一開篇所描述的情景就并不算夸張了。這樣的代碼可讀性、可維護性幾乎為0。

解決方案

PEP 484類型提示語法

那么怎么解決上述痛點呢?Python 3.5版本在語言層面加入了一個新特性:類型提示(Type Hints,詳情見開篇引文),可以以一種非常優(yōu)雅的方式來對代碼中變量的類型進行提示,大大提高了Python代碼的可讀性,例如下面這段代碼:

def hello(name:str, age:int) -> str:

return 'hello, {0}! your age is: {1}'.format(name, age)

在IPython中輸入這段代碼,然后用help函數(shù)查看hello函數(shù)的幫組文檔,顯示內(nèi)容如下:

In [10]: help(hello)

Help on function hello in module __main__:

hello(name: str, age: int) -> str

類型提示語法中,在變量或函數(shù)形參后面加:類型名稱可以指明變量的數(shù)據(jù)類型,在函數(shù)定義def語句的后面加上-> 類型名稱可以指明函數(shù)返回值的數(shù)據(jù)類型,非常方便。

PEP 484類型提示的不足之處

要注意的是,PEP 484的類型提示語言特性只在Python 3.5或更高版本才支持,而且僅僅是作為注釋性的語法元素進行解析,在編譯的時候類型提示相關的代碼都是會被當做注釋而忽略掉的,Python編譯器并不會因為有了類型提示而對代碼做任何類型檢查。

更通用的解決方案:文檔注釋

那么還有沒有更好、更通用的辦法來解決上述類型提示痛點呢?有的,文檔注釋就是一個非常好的解決辦法。

文檔注釋的優(yōu)點

清晰、準確、完善的文檔注釋可以讓Python代碼的可讀性、可維護性非常高。

不受Python語言版本的限制。

按照一定約定規(guī)范書寫的文檔注釋,可以被一些第三方IDE或語法檢查工具利用,從而可以對代碼做靜態(tài)類型檢查,在語法層面檢查代碼是否有類型錯誤,也可以做一些代碼補全方面的事情。

PyCharm風格的文檔注釋

這是一種個人比較推崇的文檔注釋格式,PyCharm IDE可以識別這種文檔注釋格式,從而進行代碼靜態(tài)語法類型檢查、代碼自動補全等操作。

下面是一個簡單的示例,在示例中用文檔注釋標注了hello函數(shù)的功能描述、每個形參變量的含義和類型、函數(shù)的返回值類型等信息:

def hello(name, age, habits = []):

'''

Say hello to someone, and print some info.

:param name: name of someone

:type name: str

:param age: age of someone

:type age: int

:param habits: habits of someone

:type habits: List[str]

:return: a hello sentence

:rtype: str

'''

return 'Hello, {name}! Your age is {age}, and your habits are {habits}.'.format(name = name, age = age, habits = habits)

將上述代碼輸入到IPython中,然后執(zhí)行hello?命令來查看hello函數(shù)的文檔注釋,結果如下:

In [28]: hello?

Signature: hello(name, age, habits=[])

Docstring:

Say hello to someone, and print some info.

:param name: name of someone

:type name: str

:param age: age of someone

:type age: int

:param habits: habits of someone

:type habits: List[str]

:return: a hello sentence

:rtype: str

可以看出函數(shù)的功能描述、每個參數(shù)的含義和數(shù)據(jù)類型、函數(shù)返回值的含義和數(shù)據(jù)類型都非常清晰明了。

numpy風格的文檔注釋

還有一種numpy項目中所使用的文檔注釋風格,也非常不錯,可以參考。一個示例如下:

def squeeze(self, axis=None):

"""

Return a possibly reshaped matrix.

Refer to `numpy.squeeze` for more documentation.

Parameters

----------

axis : None or int or tuple of ints, optional

Selects a subset of the single-dimensional entries in the shape.

If an axis is selected with shape entry greater than one,

an error is raised.

Returns

-------

squeezed : matrix

The matrix, but as a (1, N) matrix if it had shape (N, 1).

See Also

--------

numpy.squeeze : related function

Notes

-----

If `m` has a single column then that column is returned

as the single row of a matrix. Otherwise `m` is returned.

The returned matrix is always either `m` itself or a view into `m`.

Supplying an axis keyword argument will not affect the returned matrix

but it may cause an error to be raised.

Examples

--------

>>> c = np.matrix([[1], [2]])

>>> c

matrix([[1],

[2]])

>>> c.squeeze()

matrix([[1, 2]])

>>> r = c.T

>>> r

matrix([[1, 2]])

>>> r.squeeze()

matrix([[1, 2]])

>>> m = np.matrix([[1, 2], [3, 4]])

>>> m.squeeze()

matrix([[1, 2],

[3, 4]])

"""

return N.ndarray.squeeze(self, axis=axis)

Emacs編輯器自動插入PyCharm風格的文檔注釋模板

如果你平時經(jīng)常使用Emacs編輯器寫Python代碼,那么我寫了一個簡單的函數(shù),可以方便地在python-mode一鍵插入上面所講的PyCharm風格的文檔注釋。只需將下面的elisp代碼加入你的Emacs配置文件中,然后在python-mode寫完一個函數(shù)的def語句后,光標在def語句所在的行時按快捷鍵C-c C-a即可快速插入文檔注釋模板:

(defun insert-doc-annotation-below-current-line ()

"Insert doc annotations for python class or function below current line."

(interactive)

;; first, get current line text

(let ((cur-line-str (buffer-substring-no-properties (line-beginning-position) (line-end-position))))

(cond

;; judge whether current line text match python function define pattern

((string-match "^[[:space:]]*def.+?(\\(.*\\))[[:space:]]*:" cur-line-str)

;; first capture group of regex above is params list string

(setq params-str (match-string 1 cur-line-str))

;; split params list string to list, and do some strip operation

(setq params (split-string params-str ",[[:space:]]*" t "[[:space:]]*=.+?"))

;; go to end of current line and go to new line and indent

(goto-char (line-end-position))

(newline-and-indent)

;; insert head of doc annotation `'''`

(insert "'''")

(goto-char (line-end-position))

(newline-and-indent)

;; record current line number, jump back to here after inserting annotation

(setq annotation-top-line (line-number-at-pos))

(newline-and-indent)

(newline-and-indent)

;; insert each params annotation

(while params

;; NOT insert param `self`

(when (not (string-equal (car params) "self"))

(progn

(setq param (car params))

;; insert param name annotation line

(insert (format ":param %s: " param))

(newline-and-indent)

;; insert param type annotation line

(insert (format ":type %s: " param))

(newline-and-indent)

(newline-and-indent)))

(setq params (cdr params)))

;; insert return and return type annotation line

(insert ":return: ")

(newline-and-indent)

(insert ":rtype:")

(newline-and-indent)

;; insert tail of doc annotation

(insert "'''")

;; jump back to the position of annotation top

(goto-line annotation-top-line)

(indent-for-tab-command))

((string-match "^[[:space:]]*class.+?:" cur-line-str)

(goto-char (line-end-position))

(newline-and-indent)

;; insert head of doc annotation `'''`

(insert "'''")

(goto-char (line-end-position))

(newline-and-indent)

;; record current line number, jump back to here after inserting annotation

(setq annotation-top-line (line-number-at-pos))

(newline-and-indent)

;; insert tail of doc annotation

(insert "'''")

;; jump back to the position of annotation top

(goto-line annotation-top-line)

(indent-for-tab-command))

(t (message "current line NOT match neither function nor class!")))))

(add-hook 'python-mode-hook

(lambda ()

(local-set-key (kbd "C-c C-a") 'insert-doc-annotation-below-current-line)))

總結

最終決定采用文檔注釋這種更通用的方式在Python代碼中做類型提示,雖然無法做到要求其他的人都能為他們自己的Python代碼提供完備、清晰的文檔注釋,但提升代碼的可讀性可以先從自身做起,起碼可以防止那種自己也讀不懂自己的代碼、只有上帝才能看懂的尷尬局面的發(fā)生。

總結

以上是生活随笔為你收集整理的python变量类型怎么决定的_Python数据类型提示痛点的解决方案探讨的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。