學了這麼久,你真的了解函數(function)與方法(method)嗎?

2021-03-02 極客夜讀

滴滴,老Amy來啦~之前做開發的時候,一直忙著趕項目,活脫脫的就是一個秉持著「能用就行原則」的工具人[哭了],至於那顆充滿十萬個為什麼的好奇心直接被忽略~各位請細品,如果老Amy直接在公司要問領導「為什麼同樣是 def 定義,會有函數與方法兩個名稱?」,暴脾氣的領導還不跳起來給我兩下?

這我也理解,畢竟這個問題這麼問,大家肯定會向我投來同情的目光並且告訴我:「啥~定義在類裡的函數叫方法,曉得不?臭Amy」,emm...我就在想,這句話有據可依嘛?於是魯迅上身:「從來如此,便對嗎


於是乎,今天老Amy就來跟大家一起嘮嘮這方法與函數「背後的故事」~

前身

Python中的 inspect 模塊,提供了一系列的對對象進行類型檢查的函數,其中可以看到 ismethod() 與 isfunction() 函數,就是用來判斷什麼是方法(method),什麼是函數(funtion)的...[就這?別急]



首先來舉個慄子,我們直接定義一個函數test,使用 ismethod() 與 isfunction() 驗證 test 是方法還是函數,還是...成年人的世界我都要?


In [1]: import inspect

In [2]: def test():
...: print("welcome...")
...:

In [3]: inspect.ismethod(test)
Out[3]: False

In [4]: inspect.isfunction(test)
Out[4]: True


運行的結果分別是 False 和 True,說明這是一個函數而不是一個方法...emmm..那有的朋友就會說,這不跟我想的一樣嘛?那我們在命令行中來看看這兩個函數的源碼



ismethod真相

ismethod() 判斷出的是實例方法(instance method) ,最主要的是,它包含__self__屬性[介是類的]


But...類的內部定義的方法全都是真正意義上的方法(MethodType)嗎?

In [16]: class Demo(object):
...: def ins_func(self):
...: pass
...:
...: @classmethod
...: def cls_func(cls):
...: pass
...:
...: @staticmethod
...: def sta_func():
...: pass
...:

In [17]: inspect.ismethod(Demo.ins_func)
Out[17]: False

In [18]: inspect.ismethod(Demo.cls_func)
Out[18]: True

In [19]: inspect.ismethod(Demo.sta_func)
Out[19]: False



In [20]: d = Demo()

In [21]: inspect.ismethod(d.ins_func)
Out[21]: True

In [22]: inspect.ismethod(d.cls_func)
Out[22]: True

In [23]: inspect.ismethod(d.sta_func)
Out[23]: False



isfunction真相

看到 isfuntion() 所檢測的是用戶自定義函數(a user-defined function),我又開始揣測,我們使用過那麼多的Python內置函數,比如:len() 、range() 、 map()...都是啥?

In [7]: inspect.isfunction(len)
Out[7]: False

In [8]: inspect.isfunction(range)
Out[8]: False

In [9]: inspect.isfunction(map)
Out[9]: False

In [10]: type(len)
Out[10]: builtin_function_or_method


僅此而已嗎?[都怪我太年輕..,是啥類型分不清],我們需要注意的是 range() 

、 map() 等都只是看起來像函數...實際上,看圖,它們都屬於 type 


In [11]: type(range)
Out[11]: type

In [12]: type(map)
Out[12]: type


這是為啥呢?來看看官網說明文檔



上圖可以看到,Built-in Functions 裡面不僅僅只有 functions (內置函數),還有types (內置類)。也就是說,range(),map() 都是類~


「我擦..不會吧!咋整的全民誤會?」,很有必要的去看了看python2的說明文檔



這樣就很好理解了,官方在python3已經修正了python2的定義,但是我們已經習慣了全部都叫函數了呀~所以,就有了這些模稜兩可的叫法。


到這裡~老Amy好像有點暈車了~必須附上偶像的表情hhhhh,簡單的給大家做個總結叭~



總結方法

函數

用戶自定義函數可通過 aspect.isfunction() 來驗證

Built-in Functions 包含 functions(內置函數)以及types(內置類)。

如:type(len) 是 builtin_function_or_method,type(range) 則是 type。


今日雞湯


今天的雞湯有點狠,但是我們都要在快生活[emmm..]當中找到平靜又有力量的自己,謝謝你看到這裡啦~不防再來個在看關注叭~筆芯

相關焦點

  • 你還分不清什麼是方法(method),什麼是函數(function)?
    (method)和函數(function)。如果達到了編程初級/入門級水平,那麼你肯定在心中已有了初步的答案。也許在你心中已有答案了除去入參、返回值、匿名函數之類的正確的形式內容之外,你也許會說「函數就是定義在類外面的,而方法就是定義在類裡面的,跟類綁定的」。
  • Python 中的函數與方法 以及 Bound Method 和 Unbound Method
    函數與方法的區別隨著我們越來越頻繁使用Python, 我們難免會接觸到類, 接觸到類屬性和方法.但是很多新手包括我, 不知道方法 和 函數 的區別,這次簡單來討論下, 如果有哪裡認識不正確, 希望大神提點指教!
  • Python 中 staticmethod 和 classmethod 原理探究
    函數與方法對於類中定義的方法來說,通過類來調用與實例調用是不一樣的:class C:    def f(self): passprint(C.f)    # <function C.f at >print(C().f)  # <bound method C.f of >一個返回的是 function 類型,一個返回的是 method 類型。
  • 你真的了解java的lambda嗎?- java lambda用法與源碼分析
    ,後面是函數體。Thread的構造函數接收的是一個Runnable接口對象,而我們這裡的用法相當於是把一個函數當做接口對象傳遞進去了,這點理解很關鍵,這正是函數式編程的含義所在。我們注意到Runnable有個註解 @FunctionalInterface,它是jdk8才引入,它的含義是函數接口。
  • 你知道ES6箭頭函數的優缺點嗎?
    最常見的是用function關鍵字:// 函數聲明function sayHi(someone) {  return `Hello, ${someone}!>const myObject = {  method() {    console.log(this);  }};// 對象方法調用myObject.method(); //  "myObject"第三種是動態改變執行上下文的方式調用,即通過.call和.apply,this指向第一個參數代表的上下文對象:
  • 你真的了解ES6函數特性麼?
    假期轉瞬即逝,年後開工的第一天,早上是真的不想起床吖,為了不遲到閉著眼睛就穿衣服。好啦好啦,步入正題啦,打起精神哦!前言函數是所有程式語言中重要的組成部分,在Es6出現之前 JavaScript的函數語法一直沒有太大的變化,從而遺留了很多問題和隱晦的做法,導致實現一些功能需要編寫很多代碼。
  • javascript中構造函數function靜態發方法——隨手記
    構造函數function靜態發方法和屬性的定義var Constr = function (num){this.num=num;}//構造函數定義和屬性Constr.callnum=function (
  • 你真的懂 JavaScript 閉包與高階函數嗎?
    注意: 本文屬於基礎篇,如果你已經對本文相關知識點已經很了解了,那麼可以跳過本文。如果你不夠了解,或者了解的還不完整,那麼可以通過本文來複習一下 ~1.2.1 函數作為參數如果你用過 setTimeout、setInterval、ajax 請求,那麼你已經用過高階函數了,這是我們最常看到的場景:回調函數,因為它將函數作為參數傳遞給另一個函數。
  • ES6 箭頭函數大起底
    這篇文章總結了它們之間的關鍵區別,下次你選擇的時候心裡就有數了。 常規函數裡的 this (即執行上下文)指向是動態的。這也是面試常考問題之一。動態的意思就是,this的值取決於函數本身如何被調用。JavaScript 裡調用常規函數通常有 4 種方式。
  • 新手入門到進階,你不可不知的模塊,用Python獲取對象的詳細信息
    dir函數的孿生兄弟,Python中魔法方法__dir__詳解2.查看對象內部屬性信息:查看對象內部屬性的名稱和值,Python「魔法」屬性__dict__的使用3.使用幫助文檔的具體操作:你真的會用幫助文檔嗎?
  • javascript中(function(){})($)與$(function)的區別
    之前一直沒弄清楚這兩者的區別,只是發現多個(function(){})($)之間定義的方法是可以互通的,以為這個會比較好,實際運用中發現並不是這麼簡單的。1. (function(){}())與(function(){})()這兩種寫法,都是一種立即執行函數的寫法,即IIFE (Immediately Invoked Function Expression)。
  • 箭頭函數和常規函數之間的 5 個區別
    在 JavaScript 中,你可以通過多種方式去定義函數。第一種常用的方法是使用關鍵字 function:// 函數聲明function greet(who) {  return `Hello, ${who}!
  • 談談JS中的函數劫持
    函數劫持並不邪惡,關鍵是看使用的人。雖然這個概念在前端領域使用較少,但是在安全領域、自定義業務等場景下還是有一定的使用價值的。所以,這一篇文章將會和大家一起去了解一下JS中的函數劫持是什麼,有什麼用。 基本概念 函數劫持,顧名思義,即在一個函數運行之前把它劫持下來,添加我們想要的功能。當這個函數實際運行的時候,它已經不是原本的函數了,而是帶上了被我們添加上去的功能。
  • python面向對象中的self,cls,staticmethod,classmethod
    先給大家拜年,新年第一篇繼續我複習面向對象的知識,這次打算說說我疑惑挺久的self,cls,staticmethod,classmethod是幹嘛的
  • 學了這麼久,英語對你真的很重要嗎?
    只要你還在上學,英語似乎永遠陪伴著你,從小學開始,英語就與我們形影不離,可是不知道大家有沒有產生過這樣的疑問,我在英語上花了這麼多的時間我究竟收穫了什麼。要回答這個問題我們先來看看我們學英語的目的是什麼。
  • 【R函數學習】R語言時間序列函數整理
    = -0.8)),20)pacf(arima.sim(n = 1000, list(ar = 0.5, ma = -0.8)),20)【單位根檢驗】#方法1b=ts(read.csv("6_1.csv",header=T)) x=b[,1]y=b[,1]summary(ur.df(x,type="trend",selectlags="AIC
  • Python中classmethod和staticmethod的區別
    ():                passclassmethod裝飾器這個裝飾器的存在是為了讓我們可以創建類方法(這個類方法可以在函數內調用類對象,參數為cls。Student.is_full_name('Scott') 但是staticmethod裝飾的函數沒有cls/self參數,因此其裝飾的方法與類結構數據關係不太緊密,所以平常我們在實例化類之後,在實例上調用staticmethod修飾的方法,並不能操作實例數據。
  • 在JavaScript函數式編程裡使用Map和Reduce方法
    在這些函數方法裡主要的是基於JavaScript 數組對象的map()方法和reduce()方法。如果你如今還沒有使用map()和reduce()方法,那麼現在是時候開始使用了。如今絕大部分的JavaScript開發平臺都與生俱來的支持ECMAScript5。使用Map方法和reduce方法可以使你的代碼更加簡潔和更容易閱讀和更容易維護,而且把你帶到朝向更簡潔的功能開發的路上。
  • Python的@staticmethod和@classmethod的作用與區別
    但是使用@staticmethod或@classmethod,就可以不需要實例化。所以@staticmethod或@classmethod作用:使用@staticmethod或@classmethod,就可以不需要實例化,直接類名.方法名()來調用。這有利於組織代碼,把某些應該屬於某個類的函數給放到那個類裡去,同時有利於命名空間的整潔。
  • Python 函數合集:足足 68 個內置函數請收好
    python給你提供的, 拿來直接用的函數,比如print.相關內置函數語法:sorted(Iterable, key=函數(排序規則), reverse=False)Iterable: 可迭代對象key: 排序規則(排序函數), 在sorted內部會將可迭代對象中的每一個元素傳遞給這個函數的參數.