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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Python 类—类属性(私有属性、公有属性、实例属性、局部变量)类方法(实例方法、静态方法)

發(fā)布時間:2023/11/28 生活经验 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 类—类属性(私有属性、公有属性、实例属性、局部变量)类方法(实例方法、静态方法) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 創(chuàng)建類

類是對某個對象的定義,它包含有關(guān)對象動作方式的信息,包括它的名稱、方法、屬性和事件。類不存在于內(nèi)存中,因此它本身并不是對象。當(dāng)程序運(yùn)行需要引用類的代碼時,就會在內(nèi)存中創(chuàng)建一個類的新實(shí)例,即對象。雖然只有一個類,但能以這個類在內(nèi)存中創(chuàng)建多個相同類型的對象。

class Person(object):#類的方法中必須要有一個self參數(shù),但是方法被調(diào)用時,不用傳遞這個參數(shù)def get_name(self):      print "my name is: lili"def get_age(self):print "my age is : 20"def get_hoppy(self):print "My hoppy is :lvyou"boy = Person()
boy.get_name()       #但是方法被調(diào)用時,不用傳遞這個參數(shù)
boy.get_age()        #在調(diào)用get_age等方法時,boy自動將自己作為一個參數(shù)傳入方法中,因此我們稱它為self
boy.get_hoppy()

使用 PyCharm 進(jìn)行 Python 開發(fā)時,在類中定義方法時,若該方法不涉及對屬性的操作,那么PyCharm 會提示 Method xxx may be ‘static’,因?yàn)?PyCharm 會認(rèn)為該方法是一個靜態(tài)方法,而不是類方法,所提提示我們在該方法前添加 @staticmethod 裝飾器進(jìn)行裝飾。

2. 類的封裝和多態(tài)

所謂封裝,即將抽象得到的數(shù)據(jù)和行為(功能)相結(jié)合,形成一個有機(jī)整體,也就是將數(shù)據(jù)和操作數(shù)據(jù)的源代碼進(jìn)行有機(jī)整合,形成類。

其中數(shù)據(jù)和函數(shù)都是類的成員。目的是隱藏對象的屬性和實(shí)現(xiàn)細(xì)節(jié),對外公開接口,在程序中控制屬性的讀和修改的訪問級別。

封裝和多態(tài)的區(qū)別:多態(tài)可以讓用戶對不知道是什么類的對象進(jìn)行方法調(diào)用,而封裝則不用關(guān)心對象是如何創(chuàng)建的而直接進(jìn)行使用。

class MyClass(object):# 定義一個全局變量name = 'xml'def set_name(self, name):self.name = namedef get_name(self):return self.namemy = MyClass()
my.set_name('Jack')
print my.get_name()# 如果將變量存儲到全局變量name中時,實(shí)例化MyClass之后,全局變量name將會改變
my = MyClass()
my.name = 'Tom'
print my.get_name()# 對象有自己的狀態(tài),對象的狀態(tài)由它的特性名稱來描述,eg:下面she對象的內(nèi)容不影響my對象的內(nèi)容
she = MyClass()
she.set_name('angel')
print she.get_name()
print my.get_name()

3. 類的屬性

  • 私有屬性

    函數(shù)、方法或者屬性的名稱以兩個下劃線開始,則為私有類型;

  • 公有屬性

    如果函數(shù)、方法或者屬性的名稱沒有以兩個下劃線開始,則為公有屬性;

  • 實(shí)例屬性

    以self作為前綴的屬性;

  • 局部變量

    類的方法中定義的變量沒有使用self作為前綴聲明,則該變量為局部變量;

以單下劃線開頭(_foo )的代表不能直接訪問的類屬性,需通過類提供的接口進(jìn)行訪問,不能用 from xxx import 導(dǎo)入;

以雙下劃線開頭的(__foo )代表類的私有成員;

以雙下劃線開頭和結(jié)尾的(__ foo__)代表Python里特殊方法專用的標(biāo)識,如__init()__ 代表類的構(gòu)造函數(shù)。

class Fly():price = 123                      #公有的類屬性def __init__(self):self.direction = "beijing"   #公有的實(shí)例屬性 self.__city = '陜西'          #私有的實(shí)例屬性isPeople = "more people"     #局部變量if __name__ == '__main__':print Fly.price#print Fly.direction   公有的實(shí)例屬性在未實(shí)例化之前不能使用,該語句是錯誤的traveller = Fly()print traveller.direction#print traveller.__city    Fly instance has no attribute '__city'print traveller._Fly__city    #私有屬性的訪問方式:實(shí)例化對象名._類名__私有屬性名#print traveller.isPeople  局部變量不能被實(shí)例化對象traveller所引用Fly.price = traveller.price + 10print "the Fly prise is " + str(Fly.price)mytraveller = Fly()print "I think the price is " + str(mytraveller.price)

數(shù)據(jù)屬性不需要預(yù)先定義,數(shù)據(jù)屬性初次被使用時,即被創(chuàng)建并賦值。

class Data_attribute():passif __name__ == "__main__":data = Data_attribute()data.name = "我是沒有被預(yù)先定義的數(shù)據(jù)"print data.name
  • 類數(shù)據(jù)屬性屬于類本身,可以通過類名進(jìn)行訪問/修改
  • 類數(shù)據(jù)屬性也可以被類的所有實(shí)例訪問 / 修改
  • 在類定義之后,可以通過類名動態(tài)添加類數(shù)據(jù)屬性,新增的類屬性也被類和所有實(shí)例共有
  • 實(shí)例數(shù)據(jù)屬性只能通過實(shí)例訪問
  • 在實(shí)例生成后,還可以動態(tài)添加實(shí)例數(shù)據(jù)屬性,但是這些實(shí)例數(shù)據(jù)屬性只屬于該實(shí)例
class Student(object):count = 0books = []
'''
"count" "books" "name"和"age"都被稱為類的數(shù)據(jù)屬性,但是它們又分為類數(shù)據(jù)屬性和實(shí)例數(shù)據(jù)屬性
'''def __init__(self, name, age):      # 類的初始化函數(shù)"__init__"self.name = nameself.age = agepass# 1、類數(shù)據(jù)屬性Student.books.extend(['python', 'javascript'])
print 'Student book list: %s' % Student.books
# Student book list: ['python', 'javascript']
# class can add class attribute after class defineStudent.hobbies = ['reading', 'jogging', 'swimming']
print 'Student hobbies list: %s' % Student.hobbies
# Student hobbies list: ['reading', 'jogging', 'swimming']
print dir(Student)
'''
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'books', 'count', 'hobbies']
'''# 2、實(shí)例數(shù)據(jù)屬性wilber = Student('wilber', 28)
print '%s is %d years old' % (wilber.name, wilber.age)
# wilber is 28 years old
# class instance can add new attribute
# "gender" is the instance attribute only belongs to wilberwilber.gender = 'male'
print '%s is %s' % (wilber.name, wilber.gender)# class instance can access class attributeprint dir(wilber)
wilber.books.append('C#')
print wilber.bookswill = Student("Will", 27)
print "%s is %d years old" % (will.name, will.age)
# will shares the same class attribute with wilber
# will don't have the "gender" attribute that belongs to wilber
print dir(will)
print will.books

4. 類的方法

  • 類方法

    類方法使用 @classmethod 指令來聲明;

  • 類實(shí)例方法

    實(shí)例方法則無需使用指令來說明;實(shí)例方法的第一個參數(shù)必須是"self",實(shí)例方法只能通過類實(shí)例進(jìn)行調(diào)用,這時候"self"就代表這個類實(shí)例本身。通過"self"可以直接訪問實(shí)例的屬性

與實(shí)例方法和類方法不同,靜態(tài)方法沒有參數(shù)限制,既不需要實(shí)例參數(shù),也不需要類參數(shù),定義的時候使用 @staticmethod 裝飾器。

同類方法一樣,靜態(tài)法可以通過類名訪問,也可以通過實(shí)例訪問。

這三種方法的主要區(qū)別在于參數(shù),實(shí)例方法被綁定到一個實(shí)例,只能通過實(shí)例進(jìn)行調(diào)用;但是對于靜態(tài)方法和類方法,可以通過類名和實(shí)例兩種方式進(jìn)行調(diào)用。

class MyClass():def __init__(self):passdef aa(self, message):    # 類實(shí)例方法print "執(zhí)行實(shí)例方法 aa(%s,%s)" %(self,message)@classmethoddef class_method(cls, message):  # 類方法print "執(zhí)行類方法 class_method(%s,%s)" %(cls,message)@staticmethoddef static_method():    # 類靜態(tài)方法print "我是被定義的靜態(tài)方法"if __name__ == "__main__":qq = MyClass()qq.aa('hello')# My_object.aa('hello')  類實(shí)例方法aa只能被類實(shí)例調(diào)用,不能被類調(diào)用# 類方法和靜態(tài)方法可以直接被類和類實(shí)例調(diào)用qq.class_method('hello')MyClass.class_method('hello')qq.static_method()MyClass.static_method()

為什么要用到靜態(tài)方法呢? 如下示例說明:

靜態(tài)方法用到的場景就是和類相關(guān)的操作,但是又不會依賴和改變類、實(shí)例的狀態(tài),比如經(jīng)常有跟類有關(guān)系的函數(shù),我們希望它在運(yùn)行時又不需要實(shí)例和類參與的情況下直接就能調(diào)用。調(diào)用靜態(tài)方法可以無需創(chuàng)建對象。

class Robot(object):def __init__(self, data):self.data = data@staticmethoddef is_need():return Truedef reboot(self):if Robot.is_need():	# 調(diào)用類中的靜態(tài)方法print "The pc will reboot for {0}".format(self.data)def restore(self):if Robot.is_need():print "The pc will restort for {0}".format(self.data)robot1 = Robot("cmd")
robot1.reboot()
robot1.reboot()

類方法的示例

In [15]: class Student(object):...: 	num_student=0...: 	def __init__(self):...: 		Student.num_student+=1...: ...: 	@classmethod...: 	def get_num_of_instance(cls):...: 		return cls.num_student...: In [16]: s1=Student()In [17]: s1.get_num_of_instance()
Out[17]: 1In [18]: s2=Student()In [19]: s2.get_num_of_instance()
Out[19]: 2In [20]: Student.get_num_of_instance()
Out[20]: 2In [21]: s3=Student()In [22]: Student.get_num_of_instance()
Out[22]: 3

簡單記錄一下 classmethod 和 staticmethod 的區(qū)別:

classmethod 是類方法,而 staticmethod 是靜態(tài)方法。

在 Python中,靜態(tài)方法和類方法都是可以通過類對象和類對象實(shí)例訪問。但是區(qū)別是:
@classmethod 是一個函數(shù)修飾符,它表示接下來的是一個類方法,類方法的第一個參數(shù) cls,而實(shí)例方法的第一個參數(shù)是 self,表示該類的一個實(shí)例。

普通對象方法至少需要一個 self 參數(shù),代表類對象實(shí)例,類方法有類變量 cls 傳入,從而可以用 cls 做一些相關(guān)的處理。并且有子類繼承時,調(diào)用該類方法時,傳入的類變量 cls 是子類,而非父類。

對于類方法,可以通過類來調(diào)用,比如說 A 是一個類,那么我們可以通過 A.method() 來調(diào)用 A 里面的 method 方法, 也可以通過類的一個實(shí)例來調(diào)用,如 A().method() 進(jìn)行調(diào)用,首先 A() 方法會調(diào)用 A 的初始化方法進(jìn)行實(shí)例化出一個 A 的對象,然后通過該對象調(diào)用 method 方法。

靜態(tài)方法則沒有上述方法,它基本上跟一個全局函數(shù)相同,一般來說用的很少。

5. 類的繼承

繼承是指一個對象直接使用另一個對象的屬性和方法,當(dāng)一個類擁有另一個類的所有數(shù)據(jù)和操作時,就稱這兩個類之間具有繼承關(guān)系,被繼承的類稱為父類或者超類,繼承了父類或者超類的所有數(shù)據(jù)和操作的類稱為子類。

繼承類語法:

class class_name(fatherclass_name) 

fatherclass_name代表的是class_name要繼承的類 。

如何調(diào)用父類的方法:使用類名訪問父類中的方法,并在參數(shù)列表中引入對象 self。

class Father():def __init__(self):print '我是初始化Father類中的方法'print '供以后調(diào)用'class Son(Father):def __init__(self):print '我是初始化Son類中的方法'Father.__init__(self)   # 使用類名訪問父類中的方法,并在參數(shù)列表中引入對象selfchild = Son()

下面看一個例子,我們以學(xué)校的老師和學(xué)生為例,老師和學(xué)生有共同的特征:姓名、年齡、地址、喜好,不同的是老師有工資,學(xué)生有成績。

我們將學(xué)校成員歸為一個共同的類。

class SchoolMember(object):def __init__(self, name, age, addr, hoppy):self.name = nameself.age = ageself.addr = addrself.hoppy = hoppyprint '初始化的名字是%s' %self.namedef tell(self):print '姓名:%s,年齡:%s,地址:%s,喜好:%s'  %(self.name,self.age,self.addr,self.hoppy)

Teacher 類繼承 SchoolMember 類,采用新式類繼承寫法時,super() 會帶兩個參數(shù),第一個是子類的類名,第二個是 self 參數(shù)。super() 可以避免一些類繼承的潛在問題,特別是在多重繼承上。

class Teacher(SchoolMember):def __init__(self, name, age, addr, hoppy, salary):# 使用類名訪問父類中的方法,并在參數(shù)列表中引入對象selfSchoolMember.__init__(self, name, age, addr, hoppy)  # 新式類繼承寫法# super(Teacher, self).__init__(name, age, addr, hoppy)self.salary = salary    # 添加salary屬性print '我是繼承SchoolMember的老師%s' %(self.name)def tell(self):SchoolMember.tell(self)print '我這次的工資是 %s' %self.salary

Student 類繼承 SchoolMember 類

class Student(SchoolMember):def __init__(self, name, age, addr, hoppy, marks):SchoolMember.__init__(self, name, age, addr, hoppy)self.marks = marks      # 添加marks屬性print '我是繼承SchoolMember的學(xué)生%s' %(self.name)def tell(self):SchoolMember.tell(self)print '我這次的成績是 %s' %self.marks# 分別創(chuàng)建Teacher和Student的實(shí)例
t = Teacher('Tom', 40, '陜西西安', '籃球',3000)
s = Student('jack', 14, '北京', '足球', 90)members = (t, s)
for member in members:member.tell()'''
程序輸出結(jié)果如下:
我是初始化Son類中的方法
我是初始化Father類中的方法
供以后調(diào)用
初始化的名字是Tom
我是繼承SchoolMember的老師Tom
初始化的名字是jick
我是繼承SchoolMember的學(xué)生jick
姓名:Tom,年齡:40,地址:陜西西安,喜好:籃球
我這次的工資是 3000
姓名:jack,年齡:14,地址:北京,喜好:足球
我這次的成績是 90
'''

6. 類的多重繼承

子類繼承多個父類的方法:

class class_name(fatherclass_name,fatherclass_name1,......)

其中,class_name為類名,fatherclass_name,fatherclass_name1 為父類名。

class MyFather():def __init__(self):self.eye = '爸爸的眼睛是雙眼皮'print self.eyeclass MyMother():def __init__(self):self.forehead = '媽媽的額頭有點(diǎn)寬'print self.foreheadclass MyAunt():def __init__(self):self.nose = '姑姑的鼻子是高鼻梁'print self.noseclass MySelf(MyFather, MyMother, MyAunt):def __init__(self, face):print '我的眼睛是雙眼皮,別人說我是繼承的是:'MyFather.__init__(self)print '我的額頭有點(diǎn)寬,別人說我是繼承的是:'MyMother.__init__(self)print '我的鼻子有點(diǎn)寬,別人說我是繼承的是:'MyAunt.__init__(self)self.face = faceprint '我的臉型:%s' %self.face,'這下終于沒人說我像誰了'me = MySelf('偏圓吧')

7. 通過對象修改類屬性

通過對象可以修改類屬性值。但這是危險的。類屬性被所有同一類及其子類的對象共享。類屬性值的改變會影響所有的對象。

class Human(object):Age = 0Name = ["Li", "Lei"]a = Human()
b = Human()a.Age += 1
print a.Age
print b.Age          # b.Age不會改變    Age是immutable型a.Name[0] = "Wang"
print a.Name
print b.Name        # b.Name會改變     Name是mutable型'''
程序輸出結(jié)果如下:
1
0
['Wang', 'Lei']
['Wang', 'Lei']
'''

為什么immutable變量是可行的呢?原因是,在更改對象屬性時,如果屬性是immutable的,該屬性會被復(fù)制出一個副本,存放在對象的__dict__中。你可以通過下面的方式查看:

print a.__class__.__dict__
print a.__dict__

注意到類中和對象中各有一個Age。一個為0, 一個為1。所以我們在查找a.Age的時候,會先查到對象的__dict__的值,也就是1。
但mutable的類屬性,在更改屬性值時,并不會有新的副本。所以更改會被所有的對象看到。

8. 類中的方法調(diào)用其它方法

class Human(object):laugh = 'hahahahaha'def show_laugh(self):print self.laughdef laugh_10th(self):for i in range(10):self.show_laugh()li_lei = Human()
li_lei.laugh_100th()
#類屬性laugh ,在方法show_laugh()中,通過self.laugh,調(diào)用了該屬性的值。
#還可以用相同的方式調(diào)用其它方法。方法show_laugh(),在方法laugh_100th中()被調(diào)用

總結(jié)

以上是生活随笔為你收集整理的Python 类—类属性(私有属性、公有属性、实例属性、局部变量)类方法(实例方法、静态方法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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