Though classmethod and staticmethod are quite similar, there’s a slight difference in usage for both entities: classmethod must have a reference to a class object as the first parameter, whereas staticmethod can have no parameters at all.python
Let’s look at all that was said in real examples.app
儘管 classmethod 和 staticmethod 很是類似,但在用法上依然有一些明顯的區別。classmethod 必須有一個指向 類對象 的引用做爲第一個參數,而 staticmethod 能夠沒有任何參數。函數
讓咱們看幾個例子。ui
Let’s assume an example of a class, dealing with date information (this is what will be our boilerplate to cook on):this
This class obviously could be used to store information about certain dates (without timezone information; let’s assume all dates are presented in UTC).spa
很明顯,這個類的對象能夠存儲日期信息(不包括時區,假設他們都存儲在 UTC)。code
Here we have __init__, a typical initializer of Python class instances, which receives arguments as a typical instancemethod, having the first non-optional argument (self) that holds reference to a newly created instance.orm
這裏的 init 方法用於初始化對象的屬性,它的第一個參數必定是 self,用於指向已經建立好的對象。對象
We have some tasks that can be nicely done using classmethods.blog
Let’s assume that we want to create a lot of Date class instances having date information coming from outer source encoded as a string of next format (‘dd-mm-yyyy’). We have to do that in different places of our source code in project.
利用 classmethod 能夠作一些很棒的東西。
好比咱們能夠支持從特定格式的日期字符串來建立對象,它的格式是 (‘dd-mm-yyyy’)。很明顯,咱們只能在其餘地方而不是 init 方法裏實現這個功能。
So what we must do here is:
Parse a string to receive day, month and year as three integer variables or a 3-item tuple consisting of that variable.
Instantiate Date by passing those values to initialization call.
This will look like:
大概步驟:
代碼以下
理想的狀況是 Date 類自己能夠具有處理字符串時間的能力,解決了重用性問題,好比添加一個額外的方法。
For this purpose, C++ has such feature as overloading, but Python lacks that feature- so here’s when classmethod applies. Lets create another 「constructor」.
C++ 能夠方便的使用重載來解決這個問題,可是 python 不具有相似的特性。 因此接下來咱們要使用 classmethod 來幫咱們實現。
Let’s look more carefully at the above implementation, and review what advantages we have here:
We’ve implemented date string parsing in one place and it’s reusable now.
Encapsulation works fine here (if you think that you could implement string parsing as a single function elsewhere, this solution fits OOP paradigm far better).
cls is an object that holds class itself, not an instance of the class. It’s pretty cool because if we inherit our Date class, all children will have from_string defined also.
讓咱們在仔細的分析下上面的實現,看看它的好處。
咱們在一個方法中實現了功能,所以它是可重用的。 這裏的封裝處理的不錯(若是你發現還能夠在代碼的任意地方添加一個不屬於 Date 的函數來實現相似的功能,那很顯然上面的辦法更符合 OOP 規範)。 cls 是一個保存了 class 的對象(全部的一切都是對象)。 更妙的是, Date 類的衍生類都會具備 from_string 這個有用的方法。
What about staticmethod? It’s pretty similar to classmethod but doesn’t take any obligatory parameters (like a class method or instance method does).
Let’s look at the next use case.
We have a date string that we want to validate somehow. This task is also logically bound to Date class we’ve used so far, but still doesn’t require instantiation of it.
Here is where staticmethod can be useful. Let’s look at the next piece of code:
staticmethod 沒有任何須選參數,而 classmethod 第一個參數永遠是 cls, instancemethod 第一個參數永遠是 self。
So, as we can see from usage of staticmethod, we don’t have any access to what the class is- it’s basically just a function, called syntactically like a method, but without access to the object and it’s internals (fields and another methods), while classmethod does.
因此,從靜態方法的使用中能夠看出,咱們不會訪問到 class 自己 – 它基本上只是一個函數,在語法上就像一個方法同樣,可是沒有訪問對象和它的內部(字段和其餘方法),相反 classmethod 會訪問 cls, instancemethod 會訪問 self。
此文轉載文,著做權歸做者全部,若有侵權聯繫小編刪除!
原文地址:https://www.tuicool.com/articles/rMFFjmf
想要源代碼或者想了解更多的(點擊這裏查看)