Python面向對象 | 初識

 

1、面向對象編程

類 : 具備相同屬性和技能的一類事物git

對象 就是對一個類的具體的描述編程

實例化:類——>對象的過程函數

 

使用面向對象的好處:工具

  1. 使得代碼之間的角色關係更加明確
  2. 加強了代碼的可擴展性
  3. 規範了對象的屬性和技能

 

結構上面向對象能夠分爲兩部分:屬性和方法ui

  屬性又叫靜態屬性、靜態字段、靜態變量編碼

  方法又叫動態屬性、函數spa

class A:
    name = 'hello'          #靜態屬性、靜態字段、靜態變量
    def fun(self):          #動態屬性、方法、函數
        pass

新建一個類,類名的首字母最好是大寫的,規範一點,不然Pycharm有波浪號code

 

1. 類屬性

類的屬性有兩種方式查看orm

  dir(類名):查出的是一個名字列表對象

  類名.__dict__:查出的是一個字典,key爲屬性名,value爲屬性值

class Person:
    靜態變量 = 123

print(Person.__dict__) #內置的雙下劃線方法 

執行輸出:
{'__doc__': None, '靜態變量': 123, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Person' objects>,     '__dict__': <attribute '__dict__' of 'Person' objects>}

從結果中,能夠找到 '靜態變量': 123

特殊的類屬性

類名.__name__       # 類的名字(字符串)
類名.__doc__        # 類的文檔字符串
類名.__base__       # 類的第一個父類(在講繼承時會講)
類名.__bases__       # 類全部父類構成的元組(在講繼承時會講)
類名.__dict__       # 類的字典屬性
類名.__module__      # 類定義所在的模塊
類名.__class__      # 實例對應的類(僅新式類中)

2. 引用靜態變量

類名.__dict__['靜態變量名']    能夠查看,可是不能刪改
類名.靜態變量名               直接就能夠訪問,能夠刪改
del 類名.靜態變量名           刪除一個靜態變量

 

3. 引用動態變量

類名.方法名         查看這個方法的內存地址
類名.方法名(實參)       調用了這個方法,必須傳一個實參,這個實參傳給了self

 

class Person:
    靜態變量 = 123         #靜態屬性,靜態變量
    role = 'person'
    def f1(self):             #默認帶一個參數self,方法,動態屬性
        print(1234567)

#引用動態變量
Person.f1()         # 執行報錯:TypeError: f1() missing 1 required positional argument: 'self' # 提示缺乏一個參數self

隨便傳一個參數,再次執行
Person.f1(1) 

只要是類的方法,必需要傳selfself的名字,是約定俗成

 

2、面象對象  VS  函數(方法)

產生一個實例(對象)的過程:對象 = 類名()

 實例化對象的過程有幾步:

  1. 實例化對象在內存中產生一個對象空間(內存地址)。
  2. 自動執行 __init__方法,將對象空間傳給了self參數。
  3. 在 __init__方法中,給對象空間封裝一些靜態屬性。

 

1. __init__方法

初始化方法,功能就是給對象self封裝屬性

class Person:
    role = 'person' #靜態屬性
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad

summer = Person('summer','M',1,5)
print(summer.__dict__)

廣義上的屬性,是指對象的屬性

2. 類裏面的方法

  在類裏面的def 通常叫方法。沒有順序之分,通常把init放到第一個.

class Person:
    role = 'person' #靜態屬性
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad

    def attack(self):
        print('{}發起了一次攻擊'.format(self.name))


summer = Person('ss','M',1,5)
# 執行類方法,下面2種方法效果等同
Person.attack(summer)               # attack是和Person關聯起來的,因此外部能夠直接調用attack方法
summer.attack()


'''
執行輸出:
ss發起了一次攻擊
ss發起了一次攻擊
'''

 

方法的調用 :

  1.類名.方法名(對象名)              方法中的self參數就指向這個對象

  2.對象名.方法名()                  這樣寫至關於方法中的self參數直接指向這個對象,推薦使用

 

、類名、對象的使用

1. 從類名的角度研究類

① 查看類中全部的屬性和方法__dict__。雖然__dict__也能查看類中某一個屬性,可是一般用來查看類中的全部屬性和方法,不作其餘用途

② 增刪改查類中的屬性:用萬能的點(類中沒有該屬性就增,有該屬性就改)

③ 操做類中的方法:通常不經過類名(通常經過對象名

 

類名操做靜態屬性

(1)查看類中的全部內容:類名.__dict__方式

class Human:
    mind = '有思想'              # 第一部分:靜態屬性 屬性 靜態變量 靜態字段
    dic = {}
    l1 = []

    def work(self):                 # 第二部分:方法 函數 動態屬性
        print('人類會工做')

print(Human.__dict__)
print(Human.__dict__['mind'])
Human.__dict__['mind'] = '無腦'           # 報錯

經過.__dict__這種方式只能查詢,不能增刪改.第一種方式只用戶查詢所有內容(通常不用單獨屬性查詢).

 

(2)經過萬能的點 能夠增刪改查類中的單個屬性

class Human:
    mind = '有思想'

    def work(self):  # 第二部分:方法 函數 動態屬性
        print('人類會工做')

Human.walk = '直立行走'       #
del Human.mind               #
Human.mind = '無腦'          #
print(Human.mind)           #

對以上兩種作一個總結:

  • 若是想查詢類中的全部內容,經過__dict__方法;
  • 若是隻是操做單個屬性則用萬能的點的方式。

 

類名操做動態方法

  除了兩個特殊方法:靜態方法,類方法以外,通常不會經過類名操做一個類中的方法。

class Human:
    mind = '有思想'              # 第一部分:靜態屬性 屬性 靜態變量 靜態字段

    def work(self):                 # 第二部分:方法 函數 動態屬性
        print('人類會工做')

    def tools(self):
        print('人類會使用工具')

Human.work(111)
Human.tools(111)

# 下面能夠作,但不用。
Human.__dict__['work'](111)

2. 從對象的角度研究類

實例化一個對象總共發生了三件事:

  • 在內存中開闢了一個對象空間。
  • 自動執行類的__init__方法,並將這個對象空間(內存地址)傳給__init__方法的第一個位置參數self。
  • 在__init__ 方法中經過self給對象空間添加屬性。

對象操做對象空間

  • 對象查看對象空間的全部屬性__dict__
  • 對象操做對象的某個屬性,增刪改查,用萬用的點(對象中沒有該屬性就增,有該屬性就減)
  • 對象操做類空間的屬性,只能查
  • 對象操做類空間的方法:萬能的點

(1)對象查詢對象中全部屬性    對象.__dict__

class Human:
    mind = '有思想'
    language = '實用語言'

    def __init__(self,name,sex,age,hobby):
        # self 和 obj 指向的是同一個內存地址同一個空間,下面就是經過self給這個對象空間封裝四個屬性。
        self.n = name
        self.s = sex
        self.a = age
        self.h = hobby

obj = Human('barry','',18,'運動')
print(obj.__dict__)              # {'n': 'barry', 'h': '運動', 's': '男', 'a': 18}

(2)對象操做對象中的單個屬性  萬能的點 .

class Human:

    mind = '有思想'
    language = '實用語言'
    def __init__(self,name,sex,age,hobby):
        # self 和 obj 指向的是同一個內存地址同一個空間,下面就是經過self給這個對象空間封裝四個屬性。
        self.n = name
        self.s = sex
        self.a = age
        self.h = hobby

obj = Human('barry','',18,'運動')
obj.job = 'IT'                #
del obj.n                    #
obj.s = ''                  #
print(obj.s)                 #

(3)對象查看類中的屬性

class Human:

    mind = '有思想'
    language = '實用語言'
    def __init__(self,name,sex,age,hobby):
        self.n = name
        self.s = sex
        self.a = age
        self.h = hobby

obj = Human('barry','',18,'運動')
print(obj.mind)                         # 有思想
print(obj.language)                     # 實用語言

(4)對象操做類中的方法

class Human:
    mind = '有思想'
    language = '實用語言'

    def __init__(self,name,sex,age,hobby):
        self.n = name
        self.s = sex
        self.a = age
        self.h = hobby

    def work(self):
        print(self)
        print('人類會工做')

    def tools(self):
        print('人類會使用工具')

obj = Human('barry','',18,'運動')
obj.work()
obj.tools()

'''
執行輸出:
<__main__.Human object at 0x000001576C1808C8>
人類會工做
人類會使用工具
'''

一個類能夠實例化多個對象

class Human:
    mind = '有思想'
    language = '實用語言'

    def __init__(self,name,sex,age,hobby):
        self.n = name
        self.s = sex
        self.a = age
        self.h = hobby

    def work(self):
        print(self)
        print('人類會工做')

    def tools(self):
        print('人類會使用工具')

obj1= Human('李易峯','',20,'拍戲')
obj2= Human('趙麗穎','',18,'唱歌')
print(obj1,obj2)
print(obj1.__dict__)
print(obj2.__dict__)

'''
執行輸出:
<__main__.Human object at 0x00000223534C0D88> <__main__.Human object at 0x00000223534C68C8>
{'n': '李易峯', 's': '男', 'a': 20, 'h': '拍戲'}
{'n': '趙麗穎', 's': '女', 'a': 18, 'h': '唱歌'}
'''

練習:在終端輸出以下信息

小明,10歲,男,上山去砍柴
小明,10歲,男,開車去東北
小明,10歲,男,最愛大保健
老李,90歲,男,上山去砍柴
老李,90歲,男,開車去東北
老李,90歲,男,最愛大保健
老張…

class Person(object):
    def __init__(self, name, age, sex='', hobby=('上山去砍柴', '開車去東北', '最愛大保健')):
        self.name = name
        self.age = age
        self.sex = sex
        self.hobby = hobby
 
    def info(self):
        for i in self.hobby:
            print('{},{}歲,{},{}'.format(self.name, self.age, self.sex, i))
 
 
ming = Person('小明', 10)
li = Person('老李', 90)
ming.info()
li.info()

擴展題:使用面向對象的方式編碼三級菜單

將以前的代碼複製粘貼過來,切割成面向對象方式

# -*- coding: utf-8 -*-
class AreaMenu(object):
    def __init__(self):
        self.zone = {
            '山東': {
                '青島': ['四方', '黃島', '嶗山', '李滄', '城陽'],
                '濟南': ['歷城', '槐蔭', '高新', '長青', '章丘'],
                '煙臺': ['龍口', '萊山', '牟平', '蓬萊', '招遠']
            },
            '江蘇': {
                '蘇州': ['滄浪', '相城', '平江', '吳中', '崑山'],
                '南京': ['白下', '秦淮', '浦口', '棲霞', '江寧'],
                '無錫': ['崇安', '南長', '北塘', '錫山', '江陰']
            },
            '浙江': {
                '杭州': ['西湖', '江干', '下城', '上城', '濱江'],
                '寧波': ['海曙', '江東', '江北', '鎮海', '餘姚'],
                '溫州': ['鹿城', '龍灣', '樂清', '瑞安', '永嘉']
            }
        }
        self.province = list(self.zone.keys())
        self.run()

    def run(self):  # 省列表
        while True:
            print(''.center(20, '*'))

            for i in self.province:  # 打印省列表
                print('{}\t{}'.format(self.province.index(i) + 1, i))

            province_input = input('請輸入省編號,或輸入q/Q退出:').strip()

            if province_input.isdigit():
                province_input = int(province_input)

                if 0 < province_input <= len(self.province):
                    province_id = province_input - 1  # 省編號,因爲顯示加1,獲取的時候,須要減1
                    city = list(self.zone[self.province[province_id]].keys())  # 城市列表
                    self.city(province_id, city)  # 進入市區列表

                else:
                    print("\033[41;1m省編號 {} 不存在!\033[0m".format(province_input))

            elif province_input.upper() == 'Q':
                break

            else:
                print("\033[41;1m輸入省編號非法!\033[0m")

    def city(self, province_id, city):  # 市區列表
        if province_id == '' or city == '':
            return 'province_id 和 city 參數不能爲空'

        while True:
            print(''.center(20, '*'))
            for j in city:
                print('{}\t{}'.format(city.index(j) + 1, j))

            city_input = input("請輸入市編號,或輸入b(back)返回上級菜單,或輸入q(quit)退出:").strip()

            if city_input.isdigit():
                city_input = int(city_input)
                if 0 < city_input <= len(city):
                    city_id = city_input - 1  # 市編號,因爲顯示加1,獲取的時候,須要減1
                    county = self.zone[self.province[province_id]][city[city_id]]  # 縣列表
                    self.county(county)  # 進入縣列表

                else:
                    print("\033[41;1m市編號 {} 不存在!\033[0m".format(city_input))
            elif city_input.upper() == 'B':
                break
            elif city_input.upper() == 'Q':
                exit()  # 因爲在多層while循環裏面,直接exit退出便可

            else:
                print("\033[41;1m輸入市編號非法!\033[0m")

    def county(self, county):  # 縣列表
        if county == '':
            return 'county 參數不能爲空'

        while True:
            print(''.center(20, '*'))
            for k in county:
                print('{}\t{}'.format(county.index(k) + 1, k))
            # 到縣這一級,不能輸入編號了,直接提示返回菜單或者退出
            county_input = input("輸入b(back)返回上級菜單,或輸入q(quit)退出:").strip()
            if county_input == 'b':
                # 終止此層while循環,跳轉到上一層While
                break
            elif county_input == 'q':
                # 結束程序
                exit()
            else:
                print("\033[41;1m已經到底線了,請返回或者退出!\033[0m")


if __name__ == '__main__':
    AreaMenu()

 執行輸出:

相關文章
相關標籤/搜索