01-11 day15 class object

1.編程思想

1.面向過程編程 - 遇到問題直接將邏輯轉(zhuǎn)換成代碼; 邏輯思維,算法
2.函數(shù)式編程 - 遇到問題就想找一個(gè)、寫一個(gè)擁有相應(yīng)功能的函數(shù); 以函數(shù)作用工具
3.面向?qū)ο缶幊?- 遇到問題就考慮可以不可以有一個(gè)類來給我提供相應(yīng)的功能和數(shù)據(jù); 以類和對象為工具

  • python既支持函數(shù)式編程也支持面向?qū)ο缶幊?/li>

面向過程編程

import json
# json.load()

import datetime

print(datetime.datetime.today())


num1 = 34
num2 = 34
print(num1 + num2)

函數(shù)式編程:

def sum1(num1, num2):
    return num1+num2


print(sum1(1, 23))
print(sum1(23, 45))

def sum2(n):
    sum1 = 0
    for x in range(n+1):
        sum1 += x
    return sum1

print(sum2(100))
print(sum2(50))

sum1 = 0
for x in range(51):
    sum1 += x
print(sum1)


2.認(rèn)識類和對象

1.什么是類,什么是對象

類就是擁有相同功能和相同屬性的對象的集合; 類是抽象的
對象就是類的實(shí)例; 對象是具體的

人是類, 某個(gè)人就是人類的對象
車是類, 樓下停在...的那輛車就是對象
電腦是類, 我桌上這臺黑色的電腦就是對象

2.類的聲明

類中的內(nèi)容包含功能(函數(shù))和屬性(變量/屬性)

  • a.語法
    class 類名:
    類的內(nèi)容

  • b.說明
    class - python聲明類的關(guān)鍵字
    類名 - 要求:標(biāo)識符, 不能是關(guān)鍵字
    規(guī)范:駝峰式命名(通過首字母大寫來區(qū)分不同的單詞); 第一個(gè)字母要大寫
    : - 固定寫法
    類的內(nèi)容 - 包含類的方法、屬性和說明文檔
    方法就是聲明在類中的函數(shù)
    屬性就是聲明在類中的變量

3.對象的聲明

  • 語法:
    類名() - 創(chuàng)建指定的類的對象并且返回

聲明一個(gè)人類

class Person:
    """類的說明文檔: 人類"""
    num = 61    # 類中的屬性

    # 類中的方法
    def eat(self):
        print('人在吃飯')
def main():
    # 創(chuàng)建Person類的對象;p1就是對象
    p1 = Person()
    print(p1)

    # 同一個(gè)類可以創(chuàng)建多個(gè)對象
    p2 = Person()
    print(p2)

    p3 = p2
    print(p3)


if __name__ == '__main__':
    main()


3. __init __方法和構(gòu)造方法

1.init方法: __init __

__init __方法是類中的一個(gè)特殊的對象方法,專門用來對象創(chuàng)建的對象進(jìn)行初始化。
當(dāng)通過類創(chuàng)建對象的時(shí)候,系統(tǒng)就會自動(dòng)調(diào)用init方法

2.構(gòu)造方法

  • a.什么是構(gòu)造方法
    函數(shù)名和類名一樣的函數(shù)就是構(gòu)造方法, 專門用來創(chuàng)建對象。
    python中聲明類的時(shí)候系統(tǒng)會自動(dòng)創(chuàng)建這個(gè)類對應(yīng)的構(gòu)造方法。

  • b.構(gòu)造方法的執(zhí)行過程
    當(dāng)我們構(gòu)造方法的時(shí)候內(nèi)部會先在內(nèi)存中開辟空間保存對象;然后用創(chuàng)建的這個(gè)對象去調(diào)用__inin __方法,用來對對象進(jìn)行初始化;
    __init __方法調(diào)用結(jié)束后,返回對象.

def Person(*args, **kwargs):
   對象 = 創(chuàng)建對象
   對象.__init__(*args, **kwargs)
   return 對象

注意: 如果類的__init __方法除了self以外還有其他參數(shù),那么我們在創(chuàng)建對象的時(shí)候需要通過給構(gòu)造方法來給__init __方法傳參

class Person:
    # 類中__ 開頭并且__結(jié)尾的方法叫魔法方法。不需要主動(dòng)調(diào)用,系統(tǒng)會自動(dòng)調(diào)用
    def __init__(self):
        print('init被調(diào)用了')

class Dog:
    def __init__(self, x=0, y=9):
        print(x, y)
        print('dog的init')
# =============構(gòu)造方法和init的關(guān)系(了解)=============
# 構(gòu)造方法的偽代碼
def my_init(x, y, z=0):
    print(x, y, z)
    print('my_init')


def my_Dog(*args, **kwargs):
    my_init(*args, **kwargs)


my_Dog(10, 20, 34)
my_Dog(10, 34)
# ===================================================

def main():
    # 人類
    print('====')
    p1 = Person()
    print('====')

    p2 = Person()

    # 狗類
    dog1 = Dog(10, 20)
    dog2 = Dog()
    dog3 = Dog(100)
    dog4 = Dog(y=200)


if __name__ == '__main__':
    main()


4.對象屬性

1.什么是對象屬性

類中的屬性分為類的字段和對象屬性

  • a.對象屬性 - 屬性的值會因?yàn)閷ο蟛煌灰粯?,這種屬性就應(yīng)該聲明為對象屬性
    聲明在init方法中 - 位置
    以'self.屬性名 = 值'的方式來聲明(這兒的屬性就是對象屬性) - 方式
    通過'對象.屬性'的方式來使用 - 使用

  • b.類的字段 - 屬性的值不會因?yàn)閷ο蟛煌煌?,這種屬性就聲明成類的字段
    直接聲明類的里面,函數(shù)的外面的變量就是類的字段
    以'字段名 = 值'
    通過'類.字段'的方式來使用

class Person:
    # num就是類的字段
    num = 61

    # 在init方法中聲明對象屬性
    def __init__(self, name='', age=0):
        self.name = name
        self.age = age

練習(xí):創(chuàng)建Dog類,有屬性名字、類型、年齡
要求創(chuàng)建Dog的對象的時(shí)候:不能給年齡賦值,可以給類型賦值也可以不用給類型賦值,必須給名字賦值
對象方法eat:打印XXX在吃什么

class Dog:
    def __init__(self, name, type='土狗'):
        self.name = name
        self.age = 0
        self.type = type

    def eat(self, food):
        # self = dog1, food = '骨頭'
        # self = dog2, food = '屎'
        print('%s在吃%s' % (self.name, food))

練習(xí): 聲明矩形類,擁有屬性長和寬,擁有方法求面積和求周長

class Rect:
    def __init__(self, length: float, width: float):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

    def perimeter(self):
        return (self.length + self.width) * 2
def main():
    # 使用類的字段
    Person.num = 100
    print(Person.num)

    r1 = Rect(100, 98)
    print(r1.area())
    print(r1.perimeter())

    p1 = Person('小明', 18)
    # 獲取對象屬性的值
    print(p1.name, p1.age)

    p2 = Person('小紅', 20)
    # 修改對象屬性的值
    p2.name = '李四'
    print(p2.name, p2.age)

    dog1 = Dog('大黃')
    dog1.eat('骨頭')

    dog2 = Dog('旺財(cái)', '中華田園犬')
    print(dog2.name, dog2.age, dog2.type)
    dog2.eat('屎')

if __name__ == '__main__':
    main()


5.對象屬性的增、刪、改、查

python中對象的屬性支持增刪改查

屬性的增刪改查

class Person:
    def __init__(self, name='', age=0, sex='女'):
        self.name = name
        self.age = age
        self.sex = sex
class Dog:
    # __slots__魔法
    # 約束當(dāng)前類的對象最多能擁有那個(gè)屬性
    __slots__ = ('name', 'color', 'age', 'sex')

    def __init__(self, name='', color='黑色'):
        self.name = name
        self.color = color
        self.age = 10


def main():
    dog1 = Dog('大黃', '黃色')
    # dog1.age = 2
    dog1.name = 'ss'

    del dog1.color
    dog1.sex = '母'
    print(dog1.sex)

    dog2 = Dog()
    # print(dog2.sex)  # AttributeError: sex
    print('==============屬性的增刪改查===============')
    p1 = Person('小花')
    p2 = Person('小紅')

1.查(獲取對象屬性)

  • 對象.屬性 - 獲取指定對象指定屬性值;當(dāng)屬性不存在的時(shí)候會報(bào)錯(cuò)
  • getattr(對象, 屬性名:str, 默認(rèn)值) - 獲取指定對象指定屬性值;當(dāng)屬性不存在的時(shí)候如果給默認(rèn)值賦了值,程序不會報(bào)錯(cuò),并且將默認(rèn)值作為結(jié)果
    print('==============查===================')
    print(p1.name)
    # print(p1.name1)   # AttributeError:'Person' object has no attribute 'name1'

    # 屬性不確定的時(shí)候可以使用getattr
    # attr = input('屬性:')
    # print(getattr(p1, attr))

    print(getattr(p1, 'name', None))
    print(getattr(p1, 'name1', None))

增/改

  • 對象.屬性 = 值 - 當(dāng)屬性存在的是修改屬性的值;屬性不存在的時(shí)候添加屬性
  • setattr(對象, 屬性名, 值) - 當(dāng)屬性存在的是修改屬性的值;屬性不存在的時(shí)候添加屬性
    print('==============增/改===================')
    # 修改屬性
    p1.name = 'xiaohua'
    print(p1.name)
    # 添加屬性
    p1.height = 180
    print(p1.height)

    # 修改屬性
    setattr(p1, 'age', 18)
    print(p1.age)
    # 添加屬性
    setattr(p1, 'weight', 200)
    print(p1.weight)

  • del 對象.屬性
  • delattr(對象, 屬性名)
    print('==============刪=================')
    del p1.sex
    # print(p1.sex)  # AttributeError: 'Person' object has no attribute 'sex'

    delattr(p1, 'age')
    # print(p1.age)  # AttributeError: 'Person' object has no attribute 'age'

注意:對象屬性的操作,只針對操作的那一個(gè)對象,不會影響其他對象

    print(p1.height)
    # print(p2.height)  # AttributeError: 'Person' object has no attribute 'height'
    print(p2.age)


if __name__ == '__main__':
     main()


6.內(nèi)置函數(shù)

內(nèi)置屬性指的是我們創(chuàng)建類的時(shí)候系統(tǒng)自動(dòng)給我們添加的屬性(其實(shí)是通過繼承獲取到的)

class Person:
    """說明文檔:人類"""
    # 類的字段
    num = 61

    # __slots__ = ('name', 'age', 'sex')

    # 對象屬性
    def __init__(self, name='', age=0, sex='男'):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self, food):
        print('%s在吃%s' % (self.name, food))

定制對象的打印格式(當(dāng)我們通過print打印一個(gè)對象的時(shí)候,實(shí)質(zhì)就是打印對象調(diào)用repr函數(shù)的返回值)
這個(gè)函數(shù)的返回值必須是字符串

    def __repr__(self):
        # return '<%s.%s object at %s>' % (self.__class__.__module__, self.__class__.__name__, hex(id(self)))
        return '<' + str(self.__dict__)[1:-1] + ' at ' + hex(id(self)) + '>'


def main():
    """"""
    p1 = Person('小明', 18)
    print(p1)    # print(p1.__repr__())

    persons = [Person('p1', 12), Person('p2', 18, '女')]
    print(persons)
    1. 類.name - 獲取的名字(字符串)
    print(Person)
    class_name = Person.__name__
    print(Person, class_name)
    # 值是一個(gè)字符串,可以當(dāng)成字符串來用
    print(class_name.upper())
    1. 對象.class - 獲取對象對應(yīng)的類(結(jié)果是類)
    # 獲取對象p1的類
    my_class = p1.__class__
    print(my_class)
    # 可以將my_class當(dāng)成類來使用
    p2 = my_class('小花')
    print(my_class.num)
    1. 類.doc - 獲取類的說明文檔(字符串)
   print(Person.__doc__)
    print(int.__doc__)
   # 獲取對象p1對應(yīng)的類的說明文檔
    print(p1.__class__.__doc__)
  • 4.對象.dict - 將對象轉(zhuǎn)換成字典,將屬性和值作為字典的鍵值對(字典)
    注意:當(dāng)給slots屬性賦值后,對象的dict屬性就不能使用
    print(p1.__dict__)
  • 5.類.module - 獲取當(dāng)前類所在的模塊的模塊名
    print(Person.__module__)
  • 6.類.bases - 獲取當(dāng)前類的父類(元祖)
    print(Person.__bases__)

if __name__ == '__main__':
    main()


7.類方法和對象方法

1.對象方法:

a.怎么聲明: 直接聲明在類里
b.特點(diǎn): 自帶self參數(shù),調(diào)用的時(shí)候不用傳參,誰調(diào)用指向誰
c.怎么調(diào)用: 對象.方法()

2.類方法:

a.怎么聲明: 聲明函數(shù)前加@classmethod
b.特點(diǎn): 自帶默認(rèn)參數(shù)cls; 調(diào)用的不用傳參,系統(tǒng)會自動(dòng)將調(diào)用當(dāng)前函數(shù)的類傳給它
(cls是誰調(diào)用就指向誰, 類方法只能通過類來調(diào)用,所以cls就是當(dāng)前類)
類能做的事情,cls都能做

c.怎么調(diào)用: 通過類來調(diào)用, 類.方法()

3.靜態(tài)方法

a.怎么聲明:聲明函數(shù)前加@staticmethod
b.特點(diǎn): 沒有默認(rèn)參數(shù)
c.怎么調(diào)用:通過類來調(diào)用, 類.方法()

4.在類中怎么選擇使用哪種方法:

如果實(shí)現(xiàn)類中的函數(shù)的功能需要使用對象的屬性, 那么這個(gè)函數(shù)就要聲明對象方法。
實(shí)現(xiàn)函數(shù)的功能不需要對象屬性的前提下,如果需要類的字段, 就聲明成類方法
實(shí)現(xiàn)函數(shù)的功能既不需要對象屬性也不需要類的字段就聲明成靜態(tài)方法

class Person:
    num = 61

    def __init__(self):
        self.name = '張三'
def func4(self):
    print('%s對應(yīng)的對象' % self.name)
    # print('人類的數(shù)量:%d億' % Person.num)
@staticmethod
def func3():
    print(Person.num)
    print('我是靜態(tài)方法!')
@classmethod
def func2(cls):
    print(cls.num)
    print('我是類方法2')

@classmethod
def func1(cls):
    # 類能做的,cls都能做
    p1 = cls()    # 用cls來創(chuàng)建對象
    print(p1)

    cls.num = 100  # 用cls來使用類的字段

    cls.func2()   # 用cls調(diào)用類方法

    print('cls:', cls)
    print('這是一個(gè)類方法')
def main():
    print(Person)
    Person.func1()
    Person.func3()
    p1 = Person()
    p1.func4()


if __name__ == '__main__':
    main()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容