第019天 面向對象

1.什么是內置類屬性
聲明類的時候系統(tǒng)自動添加的屬性(可能是字段也可能是對象屬性)

import json

class Person:
    """
    說明文檔: 人類
    num - 人類的數(shù)量
    name - 人的名字
    """
    num = 61

    # 注意: 如果設置了__slots__的值滥朱,那么當前類的對象就不能使用__dict__屬性
    # __slots__ = ('name', 'gender', 'age')

    def __init__(self, name, gender, age):
        self.name = name
        self.gender = gender
        self.age = age

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

定制當前類的對象的打印

  1. 重寫str方法, 這個方法的返回值就是對應的打印結果(類型必須是字符串)
     def __str__(self):
         # return '姓名:{}, 年齡:{}, 性別:{}'.format(self.name, self.age, self.gender)
         return '<'+str(self.__dict__)[1:-1]+'>'

2)重寫 repr方法,這個方法的返回值就是對應的打印結果(類型必須是字符串)

    def __repr__(self):
        # return '姓名:{}, 年齡:{}, 性別:{}'.format(self.name, self.age, self.gender)
        # <'name': '小明', 'gender': '男', 'age': 18>
        return '<' + str(self.__dict__)[1:-1] + '>'
        # return 'abc'


p1 = Person('小明', '男', 18)
# 1.__name__

類的字段; 類.name - 獲取類的名字(字符串)

print(type(Person), Person)
print(type(int))
print(Person.__name__)

2.doc
類的字段; 類.doc - 獲取類的說明文檔

print(Person.__doc__)
print(int.__doc__)

3.class
對象屬性; 對象.class - 獲取對象對應的類,返回的是類
(和type(對象)功能一樣)

print(p1.__class__)
print(type(p1))
# type1 = p1.__class__
type1 = type(p1)
print(type1.__name__)
p2 = type1('小花', '女', 17)
print(p2.name, p2.gender, p2.age)

4.dict (將對象轉換成字典)
對象屬性; 對象.dict - 將對象所有的屬性和對應的值轉換成一個字典中的鍵值對(一個對象對應一個字典)
類的字段; 類.dict - 將類轉換成一個字典,字典中的元素是類中所有的字段和對應的值

print(p1.__dict__)
print(Person.__dict__)
print('p1:', p1)
print('p2:', p2)

persons = [p1, p2]
print(persons)
  1. module
    類的字段; 類.module - 獲取當前類是在哪個模塊中聲明的(返回的是模塊的名字)
print(Person.__module__)
print(bool.__module__)

6.bases
類的字段; 類.bases - 獲取當前類的父類(返回的是一個元祖)

print(Person.__bases__)

練習: 將字典轉換成對象

with open('data', 'r', encoding='utf-8') as f:
    content = json.loads(f.read())
    datas = content['data']


class Data:
    def __init__(self, dict1: dict):
        for key in dict1:
            setattr(self, key, dict1[key])

    def __repr__(self):
        return '<'+str(self.__dict__)[1:-1]+'>'


for item in datas:
    data = Data(item)
    print(data.name, type(data))
    # print(data)
1.什么是繼承

繼承就是讓子類直接擁有父類的屬性和方法
子類 - 繼承者
父類/超類 - 被繼承者

2.怎么繼承

1)語法
class 類名(父類1,父類2,..):
說明文檔
類的內容

2)說明:
() - 固定寫法背蟆,如果省略相當于(object)
聲明類的時候如果沒有寫父類肪虎,默認繼承object(object又叫基類)
父類 - 一個類的父類可以有多個劣砍,但是一般情況下只有一個(支持多繼承)

class Person:
    num = 61

    def __init__(self):
        print('Person中init')
        self.name = '小明'
        self.age = 18
        self.gender = '男'
        self.__a = 10

    def eat(self, food='米飯'):
        print('{}在吃{}'.format(self.name, food))

    @classmethod
    def show(cls):
        print('人類的數(shù)量:%d' % cls.num)

    @staticmethod
    def func1():
        print('人類')

    def func2(self):
        print('我是'+self.name)


class Student(Person):
    num = 10

    def __init__(self):
        # 在子類中添加對象屬性,需要先通過super()去調用父類的__init__來繼承父類的對象屬性
        super().__init__()
        print('Student中init')
        self.study_id = '001'
        self.class1 = 'py1904'

    # 添加功能
    def study(self):
        print(self.name+'在好好學習!')

    @staticmethod
    def func1():
        print('學生')

    def func2(self):
        print('我是學生!')
        # 在子類中可以通過super()可以去調用父類的方法
        # 注意: super()只能在對象方法和類方法中使用
        super().func2()


stu1 = Student()
print(Student.num)
print(stu1.name, stu1.age, stu1.gender)
stu1.eat()
Student.show()
print(stu1.__dict__)
Student.func1()

stu1.func2()
1.什么是getter和setter

當我們需要在獲取屬性值之前做點別的事情就需要給這個屬性添加getter扇救;
當需要給屬性賦值之前做別的事情刑枝,就需要給這個屬性添加setter

2.給屬性添加getter
  1. 屬性命名的時候前面加'_'
  2. 在@property裝飾器的后面聲明一個對象方法
    a.將屬性去掉下劃線作為方法名
    b.方法除了self以外不需要其他參數(shù)
    c.函數(shù)的返回值就是獲取這個屬性的時候得到的值
  3. 在外部使用屬性的時候香嗓,通過'對象.不帶下滑的屬性'去使用
    注意: 獲取屬性值的時候,就會自動去調用getter對應的函數(shù)
3.給屬性添加setter

屬性添加setter之前必須先添加getter
1)保證屬性名前有'_'
2)在@getter名.setter后面聲明對象方法
a.將屬性去掉下劃線作為方法名
b.需要一個self以外的參數(shù)
c.不需要返回值

  1. 在外部使用屬性的時候装畅,通過'對象.不帶下滑的屬性'去使用

注意: 當給屬性賦值的時候靠娱,實質是調用setter對應的方法


class Person:
    count = 0

    def __init__(self, name, age, gender):
        self.name = name
        self._age = age
        self._gender = 1
        self._week = 3

    # 添加getter
    @property
    def week(self):
        if self._week == 0:
            return '星期天'
        elif self._week == 1:
            return '星期一'
        elif self._week == 2:
            return '星期二'
        elif self._week == 3:
            return '星期三'
        elif self._week == 4:
            return '星期四'
        elif self._week == 5:
            return '星期五'
        elif self._week == 6:
            return '星期六'

    @property
    def age(self):
        Person.count += 1
        print('年齡值被訪問!!!!')
        return self._age

    @age.setter
    def age(self, value):
        print('年齡值被修改!')
        if not isinstance(value, int):
            raise ValueError
        if not 0 <= value <= 200:
            raise ValueError
        self._age = value

    @property
    def gender(self):
        if self._gender == 1:
            return '女'
        return '男'

    @gender.setter
    def gender(self, value):
        raise ValueError


p1 = Person('xiaoming', 18, '男')
# p1.age = 1908
# print(p1.age)
# print(p1.name, p1.age, p1.gender, p1.week)
print(p1.week)    # 這兒實質是在調用week方法獲取返回值


p2 = Person('小花', 20, '女')
p2._week = 5
print(p2.week)

print(p1.age)        # p1.age()
age1 = p1.age
print(p2.age)     # p2.age()

p1.age = 67      # p1.age(200)

print(p1.gender)
# p1.gender = '男'


# 練習: 寫一個矩形類
# 有屬性: 長掠兄、寬像云、面積、周長
# 要求從生活的角度看這個矩形
class WriteError(Exception):
    def __str__(self):
        return '修改只讀屬性!'


class Rect:
    def __init__(self, length, width):
        if isinstance(length, int) or isinstance(length, float):
            self._length = length
        else:
            raise ValueError
            # self._length = 0

        self._width = width
        self._area = 0
        self.perimeter = 0

    @property
    def length(self):
        return self._length

    @length.setter
    def length(self, value):
        if not (isinstance(value, int) or isinstance(value, float)):
            raise ValueError

        if value < 0:
            raise ValueError

        self._length = value

    @property
    def area(self):
        self._area = self._length * self._width
        return self._area

    @area.setter
    def area(self, value):
        raise WriteError


r1 = Rect(100, 300)
print(r1.area)

r1.length = 20
print(r1.area)
# r1.area = 100

r2 = Rect('abc', 'ui')
1. 類中的函數(shù)

類中的方法分為: 對象方法蚂夕、類方法和靜態(tài)方法
1)對象方法
a.怎么聲明: 直接聲明
b.怎么調用: 用對象來調用
c.特點: 有指向當前對象的self
d.什么時候用:如果實現(xiàn)函數(shù)的功能需要用到對象屬性苫费,就使用對象方法

2)類方法
a.怎么聲明: 聲明在@classmethod后面
b.怎么調用: 用類來調用, '類.類方法()'
c.特點: 有自帶的參數(shù)cls,表示當前類; 這個參數(shù)在調用的時候不用傳參双抽,系統(tǒng)會自動將當前類傳給它;
cls:誰調用就指向誰(如果是對象指向的是對象對應的類)
d.什么時候用: 如果實現(xiàn)函數(shù)的功能不需要對象屬性闲礼,但是需要類的字段, 就使用類方法

3)靜態(tài)方法
a.怎么聲明: 聲明在@staticmethod后面
b.怎么調用: 通過類來調用, '類.靜態(tài)方法()'
c.特點: 沒有默認參數(shù)
d.什么時候用: 實現(xiàn)函數(shù)的功能既不需要類也不需要對象牍汹,就使用靜態(tài)方法


class Person:
    num = 61

    def __init__(self, name: str, age: int, gender: str):
        self.name = name
        self.age = age
        self.gender = gender

    def eat(self, food: str):
        # 對象能做的事情,self都能做
        print(self.name+'在吃'+food)

    @classmethod
    def func1(cls):
        # 類能做的事情柬泽,cls都能做
        print(cls)
        t = cls('a', 10, 'b')
        print('t:',t)
        print(cls.num)
        print('這是一個類方法!')

    @staticmethod
    def func2():
        print('這是一個靜態(tài)方法!')
        print(Person.num)

    def func3(self):
        print('這是一個函數(shù)!', self.name)

    def func4(self):
        print(self.age, Person.num)


Person.func1()
print(Person)

# p1 = Person('夏明', 90, '男')
# p1.func1()

Person.func2()


p1 = Person('夏明', 90, '男')
p1.func4()


class Student(Person):
    num = 10

    @staticmethod
    def func2():
        print('這是一個靜態(tài)方法!')
        print(Student.num)


print('============1=============')
Student.func1()
Person.func1()

print('=============2============')
Student.func2()
Person.func2()
1.什么是繼承

繼承就是讓子類直接擁有父類的屬性和方法
子類 - 繼承者
父類/超類 - 被繼承者

2.怎么繼承

1)語法
class 類名(父類1,父類2,..):
說明文檔
類的內容

2)說明:
() - 固定寫法慎菲,如果省略相當于(object)
聲明類的時候如果沒有寫父類,默認繼承object(object又叫基類)
父類 - 一個類的父類可以有多個锨并,但是一般情況下只有一個(支持多繼承)


class Person:
    num = 61

    def __init__(self):
        print('Person中init')
        self.name = '小明'
        self.age = 18
        self.gender = '男'
        self.__a = 10

    def eat(self, food='米飯'):
        print('{}在吃{}'.format(self.name, food))

    @classmethod
    def show(cls):
        print('人類的數(shù)量:%d' % cls.num)

    @staticmethod
    def func1():
        print('人類')

    def func2(self):
        print('我是'+self.name)


class Student(Person):
    num = 10

    def __init__(self):
        # 在子類中添加對象屬性露该,需要先通過super()去調用父類的__init__來繼承父類的對象屬性
        super().__init__()
        print('Student中init')
        self.study_id = '001'
        self.class1 = 'py1904'

    # 添加功能
    def study(self):
        print(self.name+'在好好學習!')

    @staticmethod
    def func1():
        print('學生')

    def func2(self):
        print('我是學生!')
        # 在子類中可以通過super()可以去調用父類的方法
        # 注意: super()只能在對象方法和類方法中使用
        super().func2()


stu1 = Student()
print(Student.num)
print(stu1.name, stu1.age, stu1.gender)
stu1.eat()
Student.show()
print(stu1.__dict__)
Student.func1()

stu1.func2()
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市第煮,隨后出現(xiàn)的幾起案子解幼,更是在濱河造成了極大的恐慌,老刑警劉巖包警,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撵摆,死亡現(xiàn)場離奇詭異,居然都是意外死亡害晦,警方通過查閱死者的電腦和手機特铝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壹瘟,“玉大人鲫剿,你說我怎么就攤上這事〉竟欤” “怎么了灵莲?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澄者。 經(jīng)常有香客問我笆呆,道長请琳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任赠幕,我火速辦了婚禮俄精,結果婚禮上,老公的妹妹穿的比我還像新娘榕堰。我一直安慰自己竖慧,他們只是感情好,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布逆屡。 她就那樣靜靜地躺著圾旨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪魏蔗。 梳的紋絲不亂的頭發(fā)上砍的,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音莺治,去河邊找鬼廓鞠。 笑死,一個胖子當著我的面吹牛谣旁,可吹牛的內容都是我干的床佳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼榄审,長吁一口氣:“原來是場噩夢啊……” “哼砌们!你這毒婦竟也來了?” 一聲冷哼從身側響起搁进,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤浪感,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拷获,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篮撑,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年匆瓜,在試婚紗的時候發(fā)現(xiàn)自己被綠了赢笨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡驮吱,死狀恐怖茧妒,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情左冬,我是刑警寧澤桐筏,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站拇砰,受9級特大地震影響梅忌,放射性物質發(fā)生泄漏狰腌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一牧氮、第九天 我趴在偏房一處隱蔽的房頂上張望琼腔。 院中可真熱鬧,春花似錦踱葛、人聲如沸丹莲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甥材。三九已至,卻和暖如春性含,著一層夾襖步出監(jiān)牢的瞬間洲赵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工商蕴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留板鬓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓究恤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親后德。 傳聞我的和親對象是個殘疾皇子部宿,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內容