python类变量继承_python 类的成员及继承
1. @staticmethod 靜態(tài)方法
靜態(tài)方法不能訪問實例變量和類變量,除了身處類里面,所以只能通過類調用以外,它其實和類沒有什么關系。如果想要用它訪問實例變量或類變量,需要把實例和類傳遞給函數。
classPeople(object):def __init__(self,name):
self.name=name
@staticmethod#靜態(tài)方法,不能訪問實例變量和類變量,和類實際沒啥關系,除了把它放到類里面,然后通過類來調用它。
def getname(self,sex): #雖然有self,但是需要調用的時候手動傳入實例。
print('%s is a %s' %(self.name,sex))
people= People('LaoWang')
people.getname(people,'man') #想要訪問實例變量,只能手動傳遞實例進入!如果寫成:people.getname('man')會報錯。
2. classmethod 類方法
類方法只能訪問類變量,不能訪問實例變量。想要訪問實例變量,需要手動傳遞實例給函數。
classPeople(object):
age= 30
def __init__(self,name):
self.name=name
@staticmethod#靜態(tài)方法,不能訪問實例變量和類變量,和類實際沒啥關系,除了把它放到類里面,然后通過類來調用它。
def getname(self,sex): #雖然有self,但是需要調用的時候手動傳入實例。
print('%s is a %s' %(self.name,sex))
@classmethod#類方法,只能訪問類變量,不能訪問實例變量,如果要訪問實例變量,需要手動傳入實例。
defgetage(cls):print('age is %s' %cls.age)
people= People('LaoWang')
people.getname(people,'man') #想要訪問實例變量,只能手動傳遞實例進入!如果寫成:people.getname('man')會報錯。
people.getage()
3. @property 屬性方法
屬性方法,把一個方法變成屬性,調用時不加括號即可完成調用,就像調用一個屬性一樣。
classPeople(object):
age= 30
def __init__(self,name):
self.name=name
@staticmethod#靜態(tài)方法,不能訪問實例變量和類變量,和類實際沒啥關系,除了把它放到類里面,然后通過類來調用它。
def getname(self,sex): #雖然有self,但是需要調用的時候手動傳入實例。
print('%s is a %s' %(self.name,sex))
@classmethod#類方法,只能訪問類變量,不能訪問實例變量,如果要訪問實例變量,需要手動傳入實例。
defgetage(cls):print('age is %s' %cls.age)
@property#屬性方法,把一個方法變成屬性。調用時不用加括號。
defeat(self):print('%s is eating.' %self.name)
people= People('LaoWang')
people.getname(people,'man') #調用靜態(tài)方法。想要訪問實例變量,只能手動傳遞實例進入!如果寫成:people.getname('man')會報錯。
people.getage() #調用類方法。
people.eat #調用屬性方法。不加括號
屬性方法的修改和刪除:
classPeople(object):
age= 30
def __init__(self,name):
self.name=name
@staticmethod#靜態(tài)方法,不能訪問實例變量和類變量,和類實際沒啥關系,除了把它放到類里面,然后通過類來調用它。
def getname(self,sex): #雖然有self,但是需要調用的時候手動傳入實例。
print('%s is a %s' %(self.name,sex))
@classmethod#類方法,只能訪問類變量,不能訪問實例變量,如果要訪問實例變量,需要手動傳入實例。
defgetage(cls):print('age is %s' %cls.age)
@property#屬性方法,把一個方法變成屬性。調用時不用加括號。
defeat(self):print('%s is eating.' %self.name)
@eat.setter#屬性的修改
defeat(self,food):print('This is eat setter: %s' %food)
@eat.deleter#屬性的刪除
defeat(self):print('eat has been deleted.')
people= People('LaoWang')
people.getname(people,'man') #調用靜態(tài)方法。想要訪問實例變量,只能手動傳遞實例進入!如果寫成:people.getname('man')會報錯。
people.getage() #調用類方法。
people.eat#調用屬性方法。不加括號
people.eat = 'suger' #調用eat.setter
del people.eat #調用eat.deleter
4.?其他類成員:
classT(object):'''this is doc'''
def __new__(cls, *args, **kwargs):print('this is new func')return super().__new__(cls)def __init__(self,name):
self.name=namedefgetname(self):print(self.name)def __getitem__(self, item):print('getitem:',item)def __setitem__(self, key, value):print('setitem:',key,value)def __delitem__(self, key):print('delitem:',key)def __call__(self, *args, **kwargs):print('this is call, you should add bracket')def __str__(self):return 'you are print obj'
def __del__(self):print('When obj is been destroyed,this func would execution automatically.')
t=T('Wang') ## T是一個類,它是由type創(chuàng)建的(type是所有類的類,它可以創(chuàng)建類對象,然后類對象可以創(chuàng)建實例)。而type里面定義了一個__call__函數,所以才能使用 'T()'
print(T.__doc__) #打印類的文檔注釋
print(t.__module__)#打印對象所處的模塊名
print(t.__class__) #打印對象的類
print(t.__dict__) #打印對象的變量
print(T.__dict__) #打印類的變量
print(t) #打印對象,打印__str__方法的返回值(沒有str方法,則打印對象的內存地址)
t() #對象直接加括號,調用__call__方法
val = t['1'] #__getitem__
t['1'] = 1 #__setitem__
del t['1'] #__delitem__
del t #__del__
5.?類的類
python中萬物皆對象。類其實也是一個對象。在python中類可以創(chuàng)建實例,那么類本身又是誰創(chuàng)建的呢,答案是type
num = type(1)
string= type('my')
dictionary= type({1:'1'})print(num,string,dictionary)#
print(num.__class__,string.__class__,dictionary.__class__)#
從上面的例子可以看出,數字、字符串、字典,它們的類型都是由不同的類創(chuàng)建的。而這些類再往上追溯,它們又都是由?type?類創(chuàng)建的。所以說,type就是所有類的類。
通過type創(chuàng)建類:
#class A(object):#a = 5#def abc(self,name):#self.name = name#def getname(self):#print(self.name)
#使用type創(chuàng)建一個類,和上面的類一模一樣
definit(self, name):
self.name=namedefgetname(self):print(self.name)
A= type('A',(object,),{'a':5,'__init__':init,'getname':getname})#type第一個參數:類名#type第二個參數:當前類的基類#type第三個參數:類的成員
aa= A('Wang')
aa.getname()print(aa.a)
6.?元類?metaclass
元類就是用來造類的類,type也是一個元類,只不過它是python內建的元類,是所有類的類。我們也可以自己創(chuàng)建一個元類,用來動態(tài)的創(chuàng)建類。
class MyType(type): #創(chuàng)建元類,父類需要傳入type
def __new__(cls,name,bases,attrs): #第一步,元類的操作都在__new__中完成,第一個參數是將創(chuàng)建的類。name,將要創(chuàng)建的類。bases,將要創(chuàng)建的類的父類。attrs,類的方法和屬性的字典
print("Mytype __new__",name,bases,attrs,sep='/')print('cls',cls)return type.__new__(cls, name,bases,attrs) #如果返回一個已經存在的實例或者不返回任何值,則init不會被調用
def __init__(self,*args,**kwargs): #第二步,init
print("Mytype __init__",*args,**kwargs)def __call__(self, *args, **kwargs): #第三步,創(chuàng)建的類實例化時才執(zhí)行。類實例化時需要加括號對吧,這個括號就是__call__方法賦予的。
print("Mytype __call__", *args, **kwargs)
obj= self.__new__(self) #Foo類的new方法
print("obj....",obj,*args, **kwargs)print(self)
self.__init__(obj,*args, **kwargs)returnobjprint('-------------------------------------')class Foo(object,metaclass=MyType):def __new__(cls, *args, **kwargs):print("Foo __new__",cls, *args, **kwargs)return object.__new__(cls)def __init__(self,name):
self.name=nameprint("Foo __init__")defgetname(self):print('name is',self.name)
f= Foo("Wang")print("f",f)print("fname",f.name)
例子:使用元類來創(chuàng)建類,并動態(tài)的給所創(chuàng)建的所有類添加一個屬性:類名 = 'Hello, '+類名
class Meta(type): #元類
def __new__(cls, name,bases,attrs): #name,類名。attrs,類的所有方法屬性的字典。
attrs[name] = 'Hello, %s' % name #創(chuàng)建一個 類名 的變量,值為 ‘Hello, 類名’
print(attrs) #打印一下類的方法和屬性。
return type.__new__(cls,name,bases,attrs)class People(object,metaclass=Meta): #使用元類來定制類
age = 22peo=People()print(peo.People)
因為python是一門解釋性語言,所以按照從上往下順序執(zhí)行
class Meta --> Meta類里面的方法和屬性 --> class?People --> People里面的方法和屬性 -->?注意:此時將People里面的方法和屬性傳遞給元類,執(zhí)行元類的__new__方法、__init__方法(此例子中沒重寫) -->?peo=People()?實例化 -->?元類的__call__方法(此例子中沒重寫) -->?print(peo.People)
7.?其他封裝、繼承、多態(tài)
#類變量:修改、增加、刪除#實例變量:增加、刪除、修改
#析構函數 __del__#私有變量、私有方法:前面加 __
classCar():
region= 'China' #類變量,公有變量,每個實例化的對象都可以訪問
def __init__(self,brand,price): #構造方法,實例化
self.brand =brand
self.price=price
self.__mile = 100 #私有變量,只能內部訪問,無法通過實例化的對象進行外部訪問
def __modifyMiles(self,mile): #私有方法,只能內部調用
self.__mile +=miledefgetMiles(self):return self.__mile
def __del__(self): #析構方法,銷毀對象時自動執(zhí)行的方法(如程序運行結束、主動刪除對象)
#print('destroy obj.')
pass@staticmethod#@staticmethod是把函數嵌入到類中的一種方式,函數屬于類,但是和類沒有什么直接關系
def car_run(obj): #接受一個對象作為參數,調用這個參數的方法
obj.run()
car= Car('奔馳',300000)
car.getMiles()
car.owner= 'LaoWang' #實例化的對象也可以在外面直接添加變量
print(car.region)
car.region= 'Beijing' #相當于重新聲明了一個實例化變量
print(car.owner,car.region) #當類變量和實例化變量同時存在,首先訪問實例變量
delcar.ownerdelcar.regionprint(Car.region)classCC():pass
class EleCar(Car,CC): #多繼承,子類繼承父類Car,CC;子類不能直接調用父類的私有變量和私有方法,可以調用父類的調用了私有方法的方法
def __init__(self,brand,price,battery): #要寫父類的參數
#三種繼承方法,推薦最后一種
#Car.__init__(self,brand,price)
#super(EleCar,self).__init__(brand,price)
super().__init__(brand,price) #繼承父類,初始化父類的屬性(只初始化一個父類,按繼承的順序從左到右查找(廣度優(yōu)先),遇到的第一個帶有__init__方法的父類停止)。不管多少個父類,只寫一遍即可。
self.battery =batterydefrun(self):print('%s is running.' %self.brand)classBike(Car):def __init__(self,brand,price):
super().__init__(brand,price)defrun(self):print('%s is running.' %self.brand)
bike= Bike('永久',300)
bike.run()print('--------')
ec= EleCar('寶馬',300000,'asdf')#print(ec.getMiles())
ec.run()print('多態(tài):一個接口,多種實現(xiàn)')
Car.car_run(ec)
Car.car_run(bike)
8. 抽象類和抽象方法
from abc import ABCMeta, abstractmethod #導入抽象類和抽象方法
class Employee(metaclass=ABCMeta): #定義抽象類,抽象類不能被實例化,只能被繼承!
def __init__(self,name):
self.name=name
@abstractmethod#抽象方法,子類必須實現(xiàn)此方法!
defget_salary(self):pass
class Manager(Employee): #子類
def __init__(self,name):
super().__init__(name)def get_salary(self): #實現(xiàn)抽象類的抽象方法
return 15000
classDeveloper(Employee):def __init__(self,name,hour=0):
self.name=name
self.hour=hourdefget_salary(self):return 200*self.hourclass Factory(): #工廠模式
@staticmethoddef create(type,*args,**kwargs):return type(*args,**kwargs)
M= Factory.create(Manager,'zhongtao')
D= Factory.create(Developer,'zhangsan',160)print(f'{M.name} salary: {M.get_salary()}')print(f'{D.name} salary: {D.get_salary()}')
總結
以上是生活随笔為你收集整理的python类变量继承_python 类的成员及继承的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分子动力学模拟软件_基于GPU的分子动力
- 下一篇: 征信哪里可以打