首頁 > 後端開發 > Python教學 > 基於python3 類別的屬性、方法、封裝、繼承詳解

基於python3 類別的屬性、方法、封裝、繼承詳解

巴扎黑
發布: 2017-09-21 10:49:58
原創
2631 人瀏覽過

下面小編就為大家帶來一篇基於python3 類別的屬性、方法、封裝、繼承實例講解。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟著小編過來看看吧

Python 類別

Python中的類別提供了物件導向程式設計的所有基本功能:類別的繼承機制允許多個基類,而衍生類別可以覆寫基類中的任何方法,方法中可以呼叫基類中的同名方法。

物件可以包含任意數量和類型的資料。

python類別與c++類別相似,提供了類別的封裝,繼承、多重繼承,建構子、析構函式。

在python3中,所有類別最頂層父類別都是object類,與java類似,如果定義類別的時候沒有寫出父類,則object類別就是其直接父類別。

類別定義

類別定義語法格式如下:


class ClassName:
<statement-1>
.
.
.
<statement-N>
登入後複製
登入後複製

類別對象:建立一個類別之後,可以透過類別名稱存取、改變其屬性、方法

實例物件:類別實例化後,可以使用其屬性,可以動態的為實例物件添加屬性(類似javascript)而不影響類別物件。

類別的屬性

可以使用點(.)來存取物件的屬性

也可以使用下列函數的方式來存取屬性:

getattr(obj, name[, default]) : 存取物件的屬性

hasattr(obj,name) : 檢查是否存在一個屬性

setattr(obj,name,value) : 設定一個屬性。如果屬性不存在,會建立一個新屬性

delattr(obj, name) : 刪除屬性

##Python內建類別屬性

#__dict__ : 類別的屬性(包含一個字典,由類別的資料屬性組成)

__doc__ :類別的文件字串

__name__: 類別名稱

#__module__ : 類別定義所在的模組(類別的全名是'__main__.className',如果類別位於一個導入模組mymod中,那麼className.__module__ 等於mymod)

__bases__ : 類別的所有父類別構成元素(包含了以個由所有父類別組成的元組)


class Person:
  "Person类"
  def __init__(self, name, age, gender):
    print(&#39;进入Person的初始化&#39;)
    self.name = name
    self.age = age
    self.gender = gender
    print(&#39;离开Person的初始化&#39;)
  def getName(self):
    print(self.name)
p = Person(&#39;ice&#39;, 18, &#39;男&#39;)
print(p.name) # ice
print(p.age) # 18
print(p.gender) # 男
print(hasattr(p, &#39;weight&#39;)) # False
# 为p添加weight属性
p.weight = &#39;70kg&#39;
print(hasattr(p, &#39;weight&#39;)) # True
print(getattr(p, &#39;name&#39;)) # ice
print(p.__dict__) # {&#39;age&#39;: 18, &#39;gender&#39;: &#39;男&#39;, &#39;name&#39;: &#39;ice&#39;}
print(Person.__name__) # Person
print(Person.__doc__) # Person类
print(Person.__dict__) # {&#39;__doc__&#39;: &#39;Person类&#39;, &#39;__weakref__&#39;: <attribute &#39;__weakref__&#39; of &#39;Person&#39; objects>, &#39;__init__&#39;: <function Person.__init__ at 0x000000000284E950>, &#39;getName&#39;: <function Person.getName at 0x000000000284EA60>, &#39;__dict__&#39;: <attribute &#39;__dict__&#39; of &#39;Person&#39; objects>, &#39;__module__&#39;: &#39;__main__&#39;}
print(Person.__mro__) # (<class &#39;__main__.Person&#39;>, <class &#39;object&#39;>)
print(Person.__bases__) # (<class &#39;object&#39;>,)
print(Person.__module__) # __main__
登入後複製
登入後複製

類別的方法

在類別地內部,使用def關鍵字可以為類別定義一個方法,與一般函數定義不同,類別方法必須包含參數self,且為第一個參數。

類別的專有方法:

__init__ 建構函數,在產生物件時呼叫

__del__ 析構函數,釋放物件時使用

__repr__ 列印,轉換

__setitem__依照索引賦值

__getitem__依照索引取得值

__len__取得長度

#__cmp__比較運算

__call__函數呼叫

__add__加運算

#__sub__減運算

__mul__乘運算

#__p__除運算

__mod__求餘運算

__pow__稱方

__init__()方法是一種特殊的方法,稱為類別的建構子或初始化方法,當創建了這個類別的實例時就會呼叫該方法,與c++中建構函數類似。只要在自訂的類別中重寫__init__()方法即可。


class Person:
  def __init__(self, name, age, gender):
    print(&#39;进入Person的初始化&#39;)
    self.name = name
    self.age = age
    self.gender = gender
    print(&#39;离开Person的初始化&#39;)
  def getName(self):
    print(self.name)
# Person实例对象
p = Person(&#39;ice&#39;, 18, &#39;男&#39;)
print(p.name)
print(p.age)
print(p.gender)
p.getName()
# 进入Person的初始化
# 离开Person的初始化
# ice
# 18
# 男
# ice
登入後複製
登入後複製

析構函數__del__ ,__del__在物件消逝的時候被調用,當物件不再被使用時,__del__方法運行:

方法

實例方法:只能透過實例調用,實例方法第一個定義的參數只能是實例本身引用


class Myclass:
  def foo(self):
    print(id(self),&#39;foo&#39;)

a=Myclass()#既然是实例对象,那就要创建实例
a.foo()#输出类里的函数地址
print(id(a))#输出类对象的地址

#结果地址一样
登入後複製

類別方法:定義類別方法,要使用裝飾器@classmethod,定義的第一個參數是能是類別物件的引用,可以透過類別或實例直用


class Myclass:
@classmethod#类装饰器
  def foo2(cls):
    print(id(cls),&#39;foo2&#39;)
  #类对象,直接可以调用,不需要实例化
print(id(Myclass),&#39;yy&#39;)
Myclass.foo2()#直接可以调用
登入後複製

靜態方法:定義靜態方法使用裝飾器@staticmethod,沒有預設的必須參數,透過類別和實例直接呼叫


class Myclass:
@staticmethod#静态方法
  def foo3():
    print(&#39;foo3&#39;)

Myclass.foo3()#没有参数
a.foo3()
#结果foo3
登入後複製

類別的封裝

python透過變數名稱命名來區分屬性和方法的存取權限,預設權限相當於c++和java中的public


類別的私有屬性: __private_attrs:兩個底線開頭,聲明該屬性為私有,不能在類別地外部被使用或直接存取。在類別內部的方法中使用時self.__private_attrs。

類別的私有方法:__private_method:兩個底線開頭,宣告此方法為私有方法,不能在類別地外部呼叫。在類別的內部呼叫 self.__private_methods


雖然python不允許實例化的類別存取私有數據,但可以使用 object._className__attrName 存取屬性。其實python內部私有化的實作只是將attrName屬性變成_className__attrName而已


class Demo:
  __id = 123456
  def getId(self):
    return self.__id
temp = Demo()
# print(temp.__id) # 报错 AttributeError: &#39;Demo&#39; object has no attribute &#39;__id&#39;
print(temp.getId()) # 123456
print(temp._Demo__id) # 123456
登入後複製
登入後複製

類別的繼承

######################################## ###物件導向的程式設計帶來的主要好處之一是程式碼的重用,實作這種重複使用的方法之一是透過繼承機制。繼承完全可以理解成類別之間的類型和子類型關係。 ###

需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写作括号里,基本类是在类定义的时候,在元组之中指明的。

在python中继承中的一些特点:

1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。使用super().__init__()或parentClassName.__init__()

2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数

3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

语法:

派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后。

多态

如果父类方法的功能不能满足需求,可以在子类重写父类的方法。实例对象调用方法时会调用其对应子类的重写后的方法

python3.3 类与继承 小例

hon中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。


class Base:
  def __init__(self):
    self.data=[]
  def add(self,x):
    self.data.append(x)
  def addtwice(self,x):
    self.add(x)
    self.add(x)

# child extends base
class Child(Base):
  def plus(self,a,b):
    return a+b

oChild=Child()
oChild.add("str1")
oChild.add(999)
oChild.addtwice(4)
print(oChild.data)
print(oChild.plus(2,3))
登入後複製

对象可以包含任意数量和类型的数据。

python类与c++类相似,提供了类的封装,继承、多继承,构造函数、析构函数。

在python3中,所有类最顶层父类都是object类,与java类似,如果定义类的时候没有写出父类,则object类就是其直接父类。

类定义

类定义语法格式如下:


class ClassName:
<statement-1>
.
.
.
<statement-N>
登入後複製
登入後複製

类对象:创建一个类之后,可以通过类名访问、改变其属性、方法

实例对象:类实例化后,可以使用其属性,可以动态的为实例对象添加属性(类似javascript)而不影响类对象。

类的属性

可以使用点(.)来访问对象的属性

也可以使用以下函数的方式来访问属性:

getattr(obj, name[, default]) : 访问对象的属性

hasattr(obj,name) : 检查是否存在一个属性
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性

delattr(obj, name) : 删除属性

Python内置类属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成)

__doc__ :类的文档字符串

__name__: 类名

__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

__bases__ : 类的所有父类构成元素(包含了以个由所有父类组成的元组)


class Person:
  "Person类"
  def __init__(self, name, age, gender):
    print(&#39;进入Person的初始化&#39;)
    self.name = name
    self.age = age
    self.gender = gender
    print(&#39;离开Person的初始化&#39;)
  def getName(self):
    print(self.name)
p = Person(&#39;ice&#39;, 18, &#39;男&#39;)
print(p.name) # ice
print(p.age) # 18
print(p.gender) # 男
print(hasattr(p, &#39;weight&#39;)) # False
# 为p添加weight属性
p.weight = &#39;70kg&#39;
print(hasattr(p, &#39;weight&#39;)) # True
print(getattr(p, &#39;name&#39;)) # ice
print(p.__dict__) # {&#39;age&#39;: 18, &#39;gender&#39;: &#39;男&#39;, &#39;name&#39;: &#39;ice&#39;}
print(Person.__name__) # Person
print(Person.__doc__) # Person类
print(Person.__dict__) # {&#39;__doc__&#39;: &#39;Person类&#39;, &#39;__weakref__&#39;: <attribute &#39;__weakref__&#39; of &#39;Person&#39; objects>, &#39;__init__&#39;: <function Person.__init__ at 0x000000000284E950>, &#39;getName&#39;: <function Person.getName at 0x000000000284EA60>, &#39;__dict__&#39;: <attribute &#39;__dict__&#39; of &#39;Person&#39; objects>, &#39;__module__&#39;: &#39;__main__&#39;}
print(Person.__mro__) # (<class &#39;__main__.Person&#39;>, <class &#39;object&#39;>)
print(Person.__bases__) # (<class &#39;object&#39;>,)
print(Person.__module__) # __main__
登入後複製
登入後複製

类的方法

在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数。

类的专有方法:

__init__ 构造函数,在生成对象时调用

__del__ 析构函数,释放对象时使用

__repr__ 打印,转换

__setitem__按照索引赋值

__getitem__按照索引获取值

__len__获得长度

__cmp__比较运算

__call__函数调用

__add__加运算

__sub__减运算

__mul__乘运算

__p__除运算

__mod__求余运算

__pow__称方

__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法,与c++中构造函数类似。只需在自定义的类中重写__init__()方法即可。


class Person:
  def __init__(self, name, age, gender):
    print(&#39;进入Person的初始化&#39;)
    self.name = name
    self.age = age
    self.gender = gender
    print(&#39;离开Person的初始化&#39;)
  def getName(self):
    print(self.name)
# Person实例对象
p = Person(&#39;ice&#39;, 18, &#39;男&#39;)
print(p.name)
print(p.age)
print(p.gender)
p.getName()
# 进入Person的初始化
# 离开Person的初始化
# ice
# 18
# 男
# ice
登入後複製
登入後複製

析构函数 __del__ ,__del__在对象消逝的时候被调用,当对象不再被使用时,__del__方法运行:

类的封装

python通过变量名命名来区分属性和方法的访问权限,默认权限相当于c++和java中的public

类的私有属性: __private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs。

类的私有方法:__private_method:两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用 self.__private_methods

虽然python不允许实例化的类访问私有数据,但可以使用 object._className__attrName 访问属性。其实python内部私有化的实现只是将attrName属性变为了_className__attrName而已


class Demo:
  __id = 123456
  def getId(self):
    return self.__id
temp = Demo()
# print(temp.__id) # 报错 AttributeError: &#39;Demo&#39; object has no attribute &#39;__id&#39;
print(temp.getId()) # 123456
print(temp._Demo__id) # 123456
登入後複製
登入後複製

类的继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。

需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写作括号里,基本类是在类定义的时候,在元组之中指明的。

在python中继承中的一些特点:

1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。使用super().__init__()或parentClassName.__init__()

2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数

3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

语法:

派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后。

多态

如果父类方法的功能不能满足需求,可以在子类重写父类的方法。实例对象调用方法时会调用其对应子类的重写后的方法

python3.3 类与继承 小例


class Base:
def __init__(self):
self.data=[]
def add(self,x):
self.data.append(x)
def addtwice(self,x):
self.add(x)
self.add(x)

# child extends base
class Child(Base):
def plus(self,a,b):
return a+b

oChild=Child()
oChild.add("str1")
oChild.add(999)
oChild.addtwice(4)
print(oChild.data)
print(oChild.plus(2,3))
登入後複製

以上是基於python3 類別的屬性、方法、封裝、繼承詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板