類屬性
就像如下代碼:
class Person:
name = "張三" # 共有類屬性
__age = 18 # 私有類屬性
在類中直接定義的屬性就是類屬性,它被所有的實例對象所共有。
對於共有類屬性,在類外可通過類對象和實例對象訪問。
例如:
class Person:
name = "張三" # 共有類屬性
__age = 18 # 私有類屬性
p = Person()
print(p.name) # 通過實例對象訪問共有屬性
print(Person.name) # 通過類對象訪問共有屬性
"""
輸出結果:
張三
張三
"""
私有的類屬性在類外不能被訪問,否則會報異常。
實例屬性
- 在類中通過self.xxx或者實例對象.xxx定義的屬性就是實例屬性。
- 每個實例屬性僅在當前實例對象中有,若想要所有的實例對象有該實例屬性,則需要在__init __初始化方法中定義該實例屬性。
如下代碼所示定義實例屬性:
class Person:
def __init__(self):
self.name = "張三" # 定義實例屬性
p = Person()
print(p.name)
或者
class Person:
pass
p = Person()
p.name = "張三" # 定義實例屬性
print(p.name)
通過類對象修改類屬性的值
也許我們會想到通過實例對象去修改類屬性的值,那么它是這樣的:
class Person:
sex = "男"
def __init__(self):
self.sex = "女"
p = Person()
print(p.sex)
print(Person.sex)
"""
輸出結果:
女
男
"""
也可能是這樣想的:
class Person:
sex = "男"
p = Person()
p.sex = "女"
print(p.sex)
print(Person.sex)
"""
輸出結果:
女
男
"""
本質上它們是一樣的,並沒有修改類屬性的值,只是在當前的實例對象中添加了一個和類屬性同名實例屬性,並且之后如果通過實例對象去引用該名稱的屬性,實例屬性會強制屏蔽掉類屬性,即引用的是實例屬性,除非刪除了該實例屬性。
只有通過類對象才能修改類屬性的值
class Person:
sex = "男"
Person.sex = "女"
print(Person.sex)
"""
輸出結果:
女
"""
類方法
類對象擁有的方法就是類方法,需要用修飾器@classmethod來標識其為類方法,對於類方法,第一個參數必須是類對象,一般以cls作為第一個參數(當然可以用其他名稱的變量作為其第一個參數,但是大部分人都習慣以'cls'作為第一個參數的名字,就最好用'cls'了),能夠通過實例對象和類對象去訪問。
class People(object):
country = 'china'
#類方法,用classmethod來進行修飾
@classmethod
def getCountry(cls):
return cls.country
p = People()
print(p.getCountry()) #可以用過實例對象引用
print(People.getCountry()) #可以通過類對象引用
"""
輸出結果:
china
china
"""
類方法還有一個作用就是可以修改類屬性:
class People(object):
country = 'china'
#類方法,用classmethod來進行修飾
@classmethod
def getCountry(cls):
return cls.country
@classmethod
def setCountry(cls,country):
cls.country = country
p = People()
print(p.getCountry()) #可以用過實例對象引用
print(People.getCountry()) #可以通過類對象引用
p.setCountry('English')
print(p.getCountry())
print(People.getCountry())
"""
輸出結果:
china
china
English
English
"""
靜態方法
如果一個方法傳遞的參數不是和實例屬性有關,那么就可以把它定義成靜態方法,需要通過修飾器@staticmethod來進行修飾,靜態方法不需要多定義參數。
class People(object):
country = 'china'
@staticmethod
def getCountry():
return People.country
print (People.getCountry())
總結
從類方法和實例方法以及靜態方法的定義形式就可以看出來,類方法的第一個參數是類對象cls,那么通過cls引用的必定是類對象的屬性和方法;而實例方法的第一個參數是實例對象self,那么通過self引用的可能是類屬性、也有可能是實例屬性(這個需要具體分析),不過在存在相同名稱的類屬性和實例屬性的情況下,實例屬性優先級更高。靜態方法中不需要額外定義參數,因此在靜態方法中引用類屬性的話,必須通過類對象來引用。