2018-10-18-day15類和對(duì)象

一.recode

1.類:擁有相同屬性和相同功能的對(duì)象的集合(抽象)
屬性 -> 存儲(chǔ)數(shù)據(jù)(對(duì)象屬性,類的字段)
功能 -> 方法(對(duì)象方法,類方法和靜態(tài)方法)

class 類名(父類):
類的內(nèi)容

2.對(duì)象: 類的實(shí)例(具體)
對(duì)象 = 類名()

3.構(gòu)造方法和init方法
構(gòu)造方法: 聲明類的時(shí)候,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)函數(shù),這個(gè)函數(shù)的函數(shù)名和類名一樣。這個(gè)方法就是構(gòu)造方法。
構(gòu)造的作用就是創(chuàng)建對(duì)象,并且自動(dòng)的去調(diào)用init方法

init方法:a.系統(tǒng)在創(chuàng)建對(duì)象的時(shí)候自動(dòng)調(diào)用。
b.可以有除了self以外的其他參數(shù),如果要給這些參數(shù)傳參,需要使用構(gòu)造方法來傳
c.需要給類添加對(duì)象屬性
"""


class Person:
    num = 1

    def __init__(self, name, age):
        print(self)
        print('aaaaa')

# 偽代碼
# def Person():
#     obj = malloc(4)
#     obj.__init__()
#     return obj

# 構(gòu)造方法給init方法傳參的原理
# def dog_init(name, age, sex):
#     print(name, age, sex)
#
# def Dog(*args, **kwargs):
#     dog_init(*args, **kwargs)
#
# Dog('abc', 23, sex='男')

p2 = Person('小明', 18)
p1 = Person('小紅', 20)
# print(p1)

"""
4.對(duì)象方法: 直接聲明在類中的函數(shù)就是對(duì)象方法,有默認(rèn)參數(shù)self,并且要通過對(duì)象,調(diào)用的時(shí)候不用給self傳參
對(duì)象.對(duì)象方法,系統(tǒng)會(huì)將前面的對(duì)象傳遞給對(duì)象方法中的self
"""

class Person:
    num = 1

    def __init__(self, name, age):
        print(self)
        print('aaaaa')
        self.name = name

    def eat(self):
        # self = p1
        print(self.name)
        print('%s吃飯' % self.name)


p1 = Person('小明', 18)

p1.eat()

p2 = Person('小紅', 20)
p2.eat()

"""
5.對(duì)象的屬性
a.聲明在init方法中
b.self.屬性 = 值

要通過對(duì)象去使用(增刪改查)

6.類的字段(類的屬性)
聲明在類中,函數(shù)的外面的變量;通過類來使用(不管在哪兒用)

7.對(duì)象.dict
"""

class Person:
    num = 61

    def __init__(self, name, age=10, sex='男'):
        self.name = name
        self.age = age
        self.sex = sex

p1 = Person('小明')
p2 = Person('小紅', 18)
p3 = Person('小花', 18, '女')


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def sum(self, num):
        sum11 = self.x + self.y + num
        return sum11

p1 = Point(10, 20)
print(p1.sum(10))
二.Homework
  1. 聲明一個(gè)電腦類
    屬性:品牌、顏色、內(nèi)存大小
    方法:打游戲、寫代碼、看視頻
    a.創(chuàng)建電腦類的對(duì)象,然后通過對(duì)象點(diǎn)的方式獲取、修改、添加和刪除它的屬性
    b.通過attr相關(guān)方法去獲取、修改、添加和刪除它的屬性

class Computer:
    def __init__(self, brand, color, ram):
        self.brand = brand
        self.color = color
        self.ram = ram

    def play_game(self):
        print('玩兒連連看~')

    def coding(self):
        print('寫python代碼')

    def watch_video(self):
        print('看片兒')


cp1 = Computer('蘋果', '銀色', 256)

print(cp1.brand)
print(getattr(cp1, 'brand', '惠普'))

cp1.price = 10000
setattr(cp1, 'price', 5000)

cp1.color = '黑色'
setattr(cp1, 'color', 5000)

del cp1.ram
delattr(cp1, 'color')

2.聲明一個(gè)人的類和狗的類:
狗的屬性:名字、顏色、年齡
狗的 法:叫喚

人的屬性:名字、 年齡、狗
人的方法:遛狗
a.創(chuàng)建人的對(duì)象名字叫小明,讓他擁有一條狗 ,然后讓小明去遛狗

class Dog:
    def __init__(self, name, color, age):
        self.name = name
        self.color = color
        self.age = age

    def shout(self):
        print('嗷嗷叫~')


class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age
        self.dog = None  # 注意:dog屬性的類型應(yīng)該是Dog

    def took_the_dog(self):
        if self.dog:
            print('%s正牽著%s在散步' % (self.name, self.dog.name))
        else:
            print('沒有??,遛自己!')

    def beat(self):
        if not self.dog:
            print('沒有??!')
            return
        print('%s在打自己的??' % self.name)
        self.dog.shout()


# 創(chuàng)建人的對(duì)象
p1 = Person('小明', 18)
# 創(chuàng)建狗的對(duì)象
dog = Dog('大黃', '黃色', 3)
# 讓人擁有狗
p1.dog = dog
# 讓人去遛狗
p1.took_the_dog()
p1.beat()

3.聲明一個(gè)矩形類:
屬性: 長(zhǎng)、寬
方法:計(jì)算周長(zhǎng)和面積
a.創(chuàng)建不同的矩形,并且打印其周長(zhǎng)和面積

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

    def perimeter(self):
        return (self.length + self.width)*2

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


rect1 = Rect(3, 2)
print(rect1.perimeter(), rect1.area())

rect2 = Rect(4, 5)
print(rect2.perimeter(), rect2.area())

4.創(chuàng)建一個(gè)學(xué)生類:
屬性:姓名,年齡,學(xué)號(hào),成績(jī)
方法:答到,展示學(xué)生信息
創(chuàng)建一個(gè)班級(jí)類: 屬性:學(xué)生, 班級(jí)名
方法:添加學(xué)生,刪除學(xué)生,點(diǎn)名, 獲取班級(jí)中所有學(xué)生的平均值, 獲取班級(jí)中成績(jī)最好的學(xué)生

class Student:
    def __init__(self, name='', age=0, score=0, study_id=''):
        self.name = name
        self.age = age
        self.study_id = study_id
        self.score = score

    def replied(self):
        print('%s,到!' % self.name)

    def show_message(self):
        print(self.__dict__)


import random


class Class:
    # 類字段
    __creat_id = ('python'+str(x).rjust(3, '0') for x in range(1, 101))

    def __init__(self, name):
        self.students = []
        self.name = name

    # 添加學(xué)生
    def add_student(self):
        # 輸入學(xué)生信息
        name = input('姓名:')
        age = int(input('年齡:'))
        id = next(Class.__creat_id)
        score = random.randint(0, 100)
        # 創(chuàng)建學(xué)生對(duì)象
        stu = Student(name, age, score, id)
        self.students.append(stu)
        print('添加成功:')
        stu.show_message()

    # 刪除學(xué)生
    def del_student(self):
        del_name = input('姓名:')
        count = len(self.students)   # 刪除前學(xué)生的個(gè)數(shù)

        for stu in self.students.copy():
            if stu.name == del_name:
                self.students.remove(stu)

        if count == len(self.students):
            print('沒有該學(xué)生!')

    def call(self):
        for stu in self.students:
            print(stu.name)
            # 學(xué)生答到
            stu.replied()

    def average_score(self):
        scores = 0
        for stu in self.students:
            scores += stu.score

        return scores/len(self.students)

    def most_excellent_student(self):
        return max(self.students, key=lambda stu: stu.score)


class1 = Class('python1807')
for _ in range(5):
    class1.add_student()
三.類中方法:對(duì)象方法、類方法和靜態(tài)方法

1.對(duì)象方法:
a.直接聲明在類中
b.自帶參數(shù)self
c.通過對(duì)象來調(diào)用

2.類方法:
a.聲明在@classmethod后面的函數(shù)就是類方法
b.自帶參數(shù)cls(cls在函數(shù)調(diào)用的時(shí)候不用傳參,系統(tǒng)會(huì)自動(dòng)將調(diào)用這個(gè)方法的類賦給它)
c.通過類來調(diào)用

3.靜態(tài)方法:
a.聲明在@staticmethod后面的函數(shù)就是靜態(tài)方法
b.沒有自帶的參數(shù)
c.通過類來調(diào)用

4.怎么選擇使用哪種方法(重點(diǎn)!):
對(duì)象方法:如果實(shí)現(xiàn)函數(shù)的功能需要用到對(duì)象的屬性,那么就把這個(gè)函數(shù)聲明成對(duì)象方法
靜態(tài)方法和類方法:實(shí)現(xiàn)函數(shù)的功能不需要用到對(duì)象的屬性,就可以選擇用靜態(tài)方法或者類方法
類方法:在不使用對(duì)象屬性的前提下,需要使用類
靜態(tài)方法:既不需要對(duì)象的屬性也不需要類
"""

class Number:
    def __init__(self):
        self.value = 0
        self.type = int
        self.id = None

    @staticmethod
    def max():
        return 100

    @staticmethod
    def min():
        return -100

num = Number()
num.value = 1000
print(Number.max())


class Math:
    pi = 3.1415926

    @classmethod
    def circle_area(cls,radius):
        return cls.pi * radius ** 2

    @staticmethod
    def sum(num1, num2):
        return num1 + num2




print(Math.circle_area(3))
print(Math.circle_area(4))


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

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


class Person:
    num = 61
    # 聲明一個(gè)類方法
    @classmethod
    def destroy(cls):
        # cls指向的是當(dāng)前類。調(diào)用這個(gè)方法的類可以做的事情,cls都能做
        print('cls:',cls, cls.num)
        p2 = cls()
        print(p2)
        print('人類破壞環(huán)境')

    # 聲明一個(gè)靜態(tài)方法
    @staticmethod
    def func1():
        print(Person.num)
        p3 = Person()
        print(p3)
        print('人類的靜態(tài)方法')
四.私有化

類中的內(nèi)容默認(rèn)都是公開的(在類的外面可以使用)

1.私有化 - 將類的內(nèi)容在類的外面隱藏
在類中方法名或者屬性名前加兩個(gè)下劃線(不能以兩個(gè)下劃線結(jié)束)
私有的方法和屬性只能在類的內(nèi)部使用,不能在類的外部使用

2.私有的原理
python中沒有真正的私有化(沒有從訪問權(quán)限上去限制內(nèi)容的訪問)
私有的原理就是在私有的屬性名或者方法名前加前綴'_類名'來阻止外部直接通過帶兩個(gè)下劃線的名字去使用屬性和方法
"""

class Person:
    # 私有字段
    __num = 61
    def __init__(self, name, age):
        self.name = name
        # 私有對(duì)象屬性
        self.__age = age

    def show_info(self):
        print(self.__age)
        self.__func1()

    # 私有的對(duì)象方法
    def __func1(self):
        print('私有對(duì)象方法')


p1 = Person('小明', 23)
print(p1.name)
p1.show_info()
# print(p1.__age)

# print(Person.__num)
print(p1.__dict__)
print(p1._Person__age)
五.getter和setter

1.什么時(shí)候需要添加對(duì)象屬性的getter和setter
如果希望在通過對(duì)象.屬性獲取屬性的值之前,再干點(diǎn)兒別的事情,就可以給這個(gè)屬性添加getter。
如果希望在通過對(duì)象.屬性給屬性賦值之前,再干點(diǎn)兒別的事情,就可以給這個(gè)屬性添加setter

2.怎么添加setter和getter
getter:
a.在屬性名前加_
b.添加屬性對(duì)應(yīng)的getter
@property
def 屬性名去掉_(self):
函數(shù)體 --> 會(huì)對(duì)屬性的值進(jìn)行處理后,返回相應(yīng)的結(jié)果(必須要有返回值)

c.使用屬性的值的時(shí)候,不通過帶下劃線的屬性名去使用,而是通過沒有下劃線的屬性去使用

注意:對(duì)象.不帶下劃線的屬性 --> 調(diào)用getter對(duì)應(yīng)的函數(shù)

setter:
如果想要添加setter必須要先添加getter
a.添加setter
@getter名.setter
def 屬性名去掉_(self, 參數(shù)):
做別的事情
self.屬性名 = 處理后的值

"""

# 賦值時(shí)要求age的值只能在0-150之間,超過范圍報(bào)錯(cuò);獲取age的值的時(shí)候,返回年齡值,并且返回這個(gè)年齡對(duì)應(yīng)的階段
# class Person:
#     def __init__(self):
#         self.name
#         self.age = 18

# print(p1.age)  --> (18, 成年)
# value, jieduan  = p1.age  value -> 18, jieduan -> 成年


class Number:
    def __init__(self):
        self._value = 0
        # 0-6保存
        self._week = 3
        self.type = int
        self.id = None

    # _value添加getter和setter
    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, x):
        if not -100 <= x <= 100:
            raise ValueError
        self._value = x




    # _week的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 '星期六'

    """
    isinstance(值, 類) --> 判斷指定的值是否是指定類型(返回值是bool)
    """
    @week.setter
    def week(self, value):
        # 如果傳的值不是整型數(shù)據(jù)
        if not isinstance(value, int):
            raise ValueError
        if not 0 <= value <= 6:
            raise ValueError

        self._week = value



number = Number()
number.value = 99
print(number.week)  # number.week 實(shí)質(zhì)是在通過number去調(diào)用getter對(duì)應(yīng)的week方法
number.week = 1  # number.week = 值  實(shí)質(zhì)是通過number去調(diào)用setter對(duì)應(yīng)的week方法


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

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

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