您好,登錄后才能下訂單哦!
私有屬性分為兩類分別是對象的私有變量以及類的靜態私有變量,除了變量外,還有私有方法;在類中,所有私有的屬性和方法都是在變量的左邊加上雙下劃線的方式定義,所有的私有變量和私有方法都不能在類的外部使用
class Person():
__pwd = "123456" # 私有靜態變量
def __init__(self,name,price):
self.name = name
self.__price = price # 私有變量
# 私有方法
def __add_price(self):
return self.__price*2
eric= Person("eric",20000000)
# 私有變量和方法無法在外部調用,雖然可以通過_類名__屬性名方式調用私有變量,但不提倡使用
print(eric._Person__price)
print(eric._Person__pwd)
print(eric._Person__add_price())
20000000
123456
40000000
python的屬性其實是普通方法的變種
有兩種定義方式:
1、普通方法加上property裝飾器
2、在類中定義值為property對象的靜態字段
property是一種特殊的屬性,當我們訪問被property裝飾的函數時,執行函數內的代碼,得到返回值。
from math import pi
class Circle():
def __init__(self,radius):
self.radius = radius
@property
def perimeter(self):
return 2*pi*self.radius
@property
def area(self):
return self.radius**2*pi
c1 = Circle(5)
# 未帶裝飾器調用方法
# print(c1.area())
# 帶裝飾器時當成屬性調用
print(c1.area)
使用property裝飾器定義屬性時,要注意被property裝飾的普通方法只能有self一個參數,并且在調用時不需要加()。
在python3之后,所有的類默認繼承了object,所以說,所有的類都是新式類,新式類的property有三種訪問方式,并分別對應了三個被@property、@方法名.setter、@方法名.deleter修飾的方法
class Goods(object):
def __init__(self):
# 原價
self.original_price = 100
# 折扣
self.discount = 0.8
@property
def price(self):
# 實際價格 = 原價 * 折扣
new_price = self.original_price * self.discount
return new_price
@price.setter
def price(self, value):
self.original_price = value
@price.deleter
def price(self):
del self.original_price
obj = Goods()
print(obj.price) # 獲取商品價格
obj.price = 200 # 修改商品原價
del obj.price # 刪除商品原價
靜態字段方式沒有新式類和經典類的區別;靜態字段定義方式也有三種訪問方式:分別對應了三個被@property、@方法名.setter、@方法名.deleter修飾的方法
class Person():
def __init__(self,name):
self.__name = name
def get_name(self):
return self.__name
def set_name(self,newname):
self.__name = newname
def del_name(self):
del self.__name
NAME = property(get_name,set_name,del_name) #定義property靜態字段
obj = Person("eric")
print(obj.NAME) #調用get_name方法
obj.NAME = "111" #調用set_name方法
del Person.NAME #調用del_name方法
方法包括:普通方法、靜態方法和類方法,三種方法在內存中都歸屬于類,區別在于調用方式不同。
普通方法:由對象調用;至少一個self參數;執行普通方法時,自動將調用該方法的對象賦值給self;
類方法:由類調用; 至少一個cls參數;執行類方法時,自動將調用該方法的類復制給cls;
靜態方法:由類調用;無默認參數;
class Goods():
__discount = 0.8
def __init__(self,name,price):
self.name = name
self.__price = price
def price(self): # 普通方法
return self.__price*Goods.__discount
@classmethod
def change_discount(cls,new_discount): # 類方法
cls.__discount = new_discount
@staticmethod
def get_user_pwd(): #靜態方法
user = input('please input username: ')
pwd = input('please input pwd: ')
apple = Goods('apple',10)
Goods.change_discount(0.9) # 類方法調用
Goods.get_user_pwd() # 靜態方法調用
小結:
1、類方法
類方法是把一個方法,變成一個類中的方法,這個方法就直接可以被類調用,不需要通過對象來調用;
類方法一般用于只涉及操作靜態變量時使用。
2、靜態方法
一個函數,在與對象以及類沒什么關系的情況下,要完全的面向對象編程,此時,就可以用staticmethod將這個函數變成類中的靜態方法。
反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了計算機科學領域關于應用反射性的研究。它首先被程序語言的設計領域所采用,并在Lisp和面向對象方面取得了成績。
反射在python中通過字符串的形式操作對象相關的屬性,由四個內置函數hasattr(),getattr(),setattr(),delattr()來實現。
class Person():
country="zhongguo"
@classmethod
def sex(cls):
print(111)
#檢測是否含有某屬性
if hasattr(Person,"a1"):
getattr(Person,"a1")
#設置屬性
setattr(Person,"country","meiguo")
#獲取屬性
ret=getattr(Person,"country")
#刪除屬性
delattr(Person,"country")
print(ret)
isinstance(obj,cls)檢查obj是否是cls的對象
issubclass(sub,super)檢查sub類是否是super類的子類
classA():pass
classB(A):pass
a=A()
print(isinstance(a,A))
print(issubclass(A,B))
print(issubclass(B,A))
__doc__
表示類的描述信息
class Person():
'''__doc__:description '''
pass
print(Person.__doc__)
__doc__:description
__init__
類實例化對象時,自動執行類中的init方法
class Person():
def __init__(self,name,age):
self.name = name
self.age = age
stu = Person("eric",20)
__del__
析構方法,當對象在內存中被釋放時,自動觸發執行。
再刪除一個對象之前進行一些收尾工作
__call__
對象后加括號,觸發執行
class Person():
def __init__(self,name,age):
self.name = name
self.age =age
def __call__(self, *args, **kwargs):
# 打印對象的所有屬性
for key in self.__dict__:
print(key,self.__dict__[key])
eric = Person("eric",22)
eric()
__dict__
保存類或對象中的成員
classPerson():
country="china"
def__init__(self,name,age):
self.name=name
self.age=age
#獲取類的成員--靜態字段和方法
print(Person.__dict__)
#獲取對象的成員
obj=Person("eric",22)
print(obj.__dict__)
__str__和__repr__
字符串顯示
打印一個對象時,就是調用這個對象所屬類的__str__
方法,
調用__str__
方法,會返回調用這個方法的對象的內存地址
字符串格式化%s以及str()直接打印實際上都是調用的__str__
方法
%r,repr()都是調用的__repr__
方法
repr時str的備份,str不能做repr的備份
print(obj)/%s/str(obj)的時候,實際上是內部調用了obj.__str__
方法,如果由str方法,那么他返回的必定是一個字符串
如果沒有str方法,會先找本類中的__repr__
方法
class A:
def __str__(self):
return"Aobject"
def __repr__(self):
return"repr"
a=A()
#打印一個對象時,就是調用這個對象所屬類的__str__方法,
print(a)
print(repr(a))
用于索引操作,分別是獲取,設置,刪除
class Person():
def __getitem__(self,key):
print("__getitem__",key)
def __setitem__(self,key,value):
print("__setitem__",key,value)
def __delitem__(self,key):
print("__delitem__",key)
obj=Person()
ret=obj['k1']#自動觸發執行__getitem__
obj['k2']='eric'#自動觸發執行__setitem__
delobj['k1']#自動觸發執行__delitem__
__len__
統計數量,len(obj)其實就是調用自身所屬類或父類的__len__
方法
class Person():
def __init__(self,name,age):
self.name=name
self.age=age
def __len__(self):
returnlen(self.__dict__)
eric=Person("eric",22)
print(len(eric))
__new__
通過類的構造方法創建對象
class Person():
def func(self):pass
eric=Person()
單例模式
通過new方法來實現的單例模式
單例模式:一個類始終只有一個實例,當你第一次實例化這個類的時候,就創建一個實例化的對象,當你之后再來實例化的時候,就用之前創建的對象
class A():
__instance=False
def __init__(self,name,age):
self.name=name
self.age=age
def __new__(cls,*args,**kwargs):
if cls.__instance:
return cls.__instance
cls.__instance=object.__new__(cls)
returncls.__instance
egon=A("eric",22)
jonny=A("jonny",28)
print(egon)
print(jonny)
結果:
<main.A object at 0x0000015C2480E5C0>
<main.A object at 0x0000015C2480E5C0>
__eq__
判斷兩個對象是否相等(通過內存地址)
class Person():
def __init__(self,name):
self.name = name
obj1 = Person("eric")
obj2 = Person("eric")
print(obj1 == obj2)
結果為False,是因為兩個對象的值雖然一樣,但是在內存中的地址不一樣;我們可以重寫__eq__
方法,使其比對對象的值而非內存地址。
class Person():
def __init__(self,name):
self.name = name
def __eq__(self, other):
if self.name == self.name:
return True
else:
return False
obj1 = Person("eric")
obj2 = Person("eric")
print(obj1 == obj2)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。