python-12-面对对象进阶

目录

00-函数练习答案

01-面对对象练习

02-self的注意事项

03-运算符相关的魔法方法

04-内置函数

05-把对象当做一个字典使用

06-对象属性和类属性

07-私有属性的使用

08-类方法和静态方法

09-静态方法的使用

10-单例设计模式


00-函数练习答案

# 编写一个函数,求多个数中的最大值
import random


def get_max(*args):
    x = args[0]
    for arg in args:
        if arg > x:
            x = arg
    return x


# 编写一个函数,实现摇骰子的功能,打印N个骰子的点数和
def get_sum(n):
    m = 0
    for i in range(n):
        x = random.randint(1, 6)
        m += x
    return m


# 编写一个函数,提取指定字符串中所有的字母,然后拼接在一起产生一个新的字符串
def get_alphas(word):
    new_str = ''
    for w in word:
        if w.isalpha():
            new_str += w
    return new_str


# 写一个函数,默认求10的阶乘,也可以求其他数字的阶乘
def get_factorial(n=10):
    x = 1
    for i in range(1, n + 1):
        x *= i
    return x


# 写一个函数,求多个数的平均值
def get_average(*args):
    x = 0
    for arg in args:
        x += arg
    return x / len(args)


# 写一个自己的capitalize函数,能够将指定字符串的首字母变成大写字母
def my_capitalize(word):
    c = word[0]
    if 'z' >= c >= 'a':
        new_str = word[1:]
        return c.upper() + new_str
    return word


# 写一个自己的endswith函数,判断一个字符串是否以指定的字符串结束
def my_endswith(old_str, str1):
    return old_str[-len(str1):] == str1


# 写一个自己的isdigit函数,判断一个字符串是否是纯数字字符串
def my_digit(old_str):
    for s in old_str:
        if not '0' <= s <= '9':
            return False
    return True


# 写一个自己的upper函数,将一个字符串中所有的小写字母变成大写字母
# a==>97  A ==> 65   32
def my_upper(old_str):
    new_str = ''
    for s in old_str:
        if 'a' <= s <= 'z':
            upper_s = chr(ord(s) - 32)
            new_str += upper_s
        else:
            new_str += s
    return new_str


# 写一个函数实现自己in操作,判断指定序列中,指定的元素是否存在
def my_in(it, ele):
    for i in it:
        if i == ele:
            return True
    else:
        return False


# 写一个自己的replace函数,将指定字符串中指定的旧字符串转换成指定的新字符串
# return new_str.join(all_str.split(old_str))
# def my_replace(all_str, old_str, new_str):
def my_replace(all_str, old_str, new_str):
    result = ''
    i = 0
    while i < len(all_str):
        temp = all_str[i:i + len(old_str)]
        if temp != old_str:
            result += all_str[i]
            i += 1
        else:
            result += new_str
            i += len(old_str)
    return result


# 写一个自己的max函数,获取指定序列中元素的最大值。如果序列是字典,取字典值的最大值
def get_max2(seq):
    # if type(seq) == dict:
    if isinstance(seq, dict):  # 看对象seq是否是通过dict类创建出来的实例
        seq = list(seq.values())
    x = seq[0]
    for i in seq:
        if i > x:
            x = i
    return x


print(get_max(1, 9, 6, 3, 4, 5))
print(get_sum(5))
print(get_alphas('hello123good456'))
print(get_factorial())
print(get_average(1, 2, 3, 4, 5, 6))
print(my_capitalize('hello'))
print(my_capitalize('34hello'))
print(my_endswith('hello', 'lxo'))
print(my_digit('12390'))
print(my_upper('hel34lo'))
print(my_in(['zhangsan', 'lisi', 'wangwu'], 'jack'))
print(my_in({'name': 'zhangsan', 'age': '18'}, 'name'))
print(my_replace('how you and you fine you ok', 'you', 'me'))
# ['zhangsan','lisi','wangwu']  ==> zhangsan_lisi_wangwu

print(get_max2([2, 4, 8, 1, 9, 0, 7, 5]))
print(get_max2({'x': 10, 'y': 29, 'z': 32, 'a': 23, 'b': 19, 'c': 98}))

01-面对对象练习

# 房子(House) 有 户型、总面积 、剩余面积(等于总面积的60%) 和 家具名称列表 属性
# 新房子没有任何的家具
# 将 家具的名称 追加到 家具名称列表 中
# 判断 家具的面积 是否 超过剩余面积,如果超过,提示不能添加这件家具

# 家具(Furniture) 有 名字 和 占地面积属性,其中
# 席梦思(bed) 占地 4 平米
# 衣柜(chest) 占地 2 平米
# 餐桌(table) 占地 1.5 平米
# 将以上三件 家具 添加 到 房子 中
# 打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表


class House(object):
    # 缺省参数
    def __init__(self, house_type, total_area, fru_list=None):
        if fru_list is None:  # 如果这个值是None
            fru_list = []  # 将fru_list设置为空列表
        self.house_type = house_type
        self.total_area = total_area
        self.free_area = total_area * 0.6
        self.fru_list = fru_list

    def add_fru(self, x):  # x = bed
        if self.free_area < x.area:
            print('剩余面积不足,放不进去了')
        else:
            self.fru_list.append(x.name)
            self.free_area -= x.area

    # def __repr__(self):
    def __str__(self):
        return '户型={},总面积={},剩余面积={},家具列表={}'.format(self.house_type, self.total_area, self.free_area, self.fru_list)


class Furniture(object):
    def __init__(self, name, area):
        self.name = name
        self.area = area


# 创建房间对象的时候,传入户型和总面积
house = House('一室一厅', 20)  # 12

sofa = Furniture('沙发', 10)
bed = Furniture('席梦思', 4)
chest = Furniture('衣柜', 2)
table = Furniture('餐桌', 1.5)

# 把家具添加到房间里(面向对象关注点:让谁做)
house.add_fru(sofa)
house.add_fru(bed)
house.add_fru(chest)
house.add_fru(table)

# print(house.__str__())
print(house)  # print打印一个对象的时候,会调用这个对象的__repr__或者__str__ 方法,获取它们的返回值

02-self的注意事项

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self):
        print(self.name + '正在吃东西')


p1 = Person('张三', 18)
p2 = Person('李四', 20)

p1.eat()

03-运算符相关的魔法方法

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

    def __eq__(self, other):
        # if self.name == other.name and self.age == other.age:
        #     return True
        # return False
        return self.name == other.name and self.age == other.age

    # def __ne__(self, other):   使用 != 运算符会自动调用这个方法

    def __gt__(self, other):  # greater than 使用 > 会自动调用这个方法
        return self.age > other.age

    # def __ge__(self, other):  使用 >= 运算符会自动调用
    # def __lt__(self, other):  # less than  p1<p2
    # def __le__(self, other):  # <=

    def __add__(self, other):  # +
        return self.age + other.age

    def __sub__(self, other):  # -
        return self.age - other

    def __mul__(self, other):  # *
        return self.name * other

    # def __truediv__(self, other):  # /
    # def __pow__(self, power, modulo=None):
    def __str__(self):
        return 'hello'

    def __int__(self):
        return 20

    def __float__(self):
        return 100.5


p1 = Person('zhangsan', 18)
p2 = Person('zhangsan', 18)
p3 = Person('lisi', 19)
print(p1 is p2)  # False

# == 运算符本质其实是调用对象的 __eq__ 方法,获取 __eq__方法的返回结果
# a == b  => a.__eq__(b)
print(p1 == p2)  # True  p1.__eq__(p2)

# != 本质是调用 __ne__ 方法 或者 __eq__ 方法取反
print(p1 != p2)  # False

print(p1 > p2)

print(p1 + p2)
print(p1 - 2)

print(p1 * 2)

# str()将对象转换成为字符串,会自动调用 __str__ 方法
# 1. str()  2. 打印对象也会调用
# print(p1)
x = str(p1)  # 转换成为字符串。默认会转换成为类型+内存地址
print(x)

# int()  ==> 调用对象的 __int__ 方法
print(int(p1))
print(float(p1))

print(int(p1))  # 只调用了__int__,没有调用 __str__
print(p1)  # 调用 __str__

04-内置函数

class Person(object):
    __slots__ = ('name', 'age')
    """
    这是一个人类
    """

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

    def eat(self):
        print(self.name + '正在吃饭')


# 'name':'zhangsan','age':18,'eat':<function >
p = Person('张三', 18)
print(dir(p))
print(p.__class__)  # <class '__main__.Person'>
print(p.__dict__)  # {'name': '张三', 'age': 18} 把对象属性和值转换成为一个字典
# print(p.__dir__())  # 等价于 dir(p)
print(p.__doc__)  # 对象名.__doc__
print(Person.__doc__)  # 类名.__doc__
print(p.__module__)  # __main__

05-把对象当做一个字典使用

class Person(object):
    def __init__(self, name, age, city):
        self.name = name
        self.age = age
        self.city = city

    def __setitem__(self, key, value):  # key='age',value=20
        # print('setitem方法被调用了,key={},value={}'.format(key, value))
        self.__dict__[key] = value

    def __getitem__(self, item):
        return self.__dict__[item]


p = Person('张三', 18, '襄阳')
print(p.__dict__)  # 将对象转换成为字典 {'name': '张三', 'age': 18,'city': '襄阳'}

# 不能直接把一个对象当做字典来使用
p['age'] = 20  # [] 语法会调用对象的 __setitem__方法
p['name'] = 'tony'

print(p.name, p.age)
print(p['name'])  # 会调用 __getitem__ 方法

06-对象属性和类属性

class Person(object):
    type = '人类'  # 这个属性定义在类里,函数之外,我们称之为类属性

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


# 对象 p1和p2 是通过 Person 类创建出来的实例对象
# name 和 age 是对象属性,在__init__ 方法里,以参数的形式定义的
# 每一个实例对象都会单独保存一份的属性
# 每个实例对象之间的属性没有关联,互不影响
p1 = Person('张三', 18)
p2 = Person('李四', 19)

# 类属性可以通过类对象和实例对象获取
print(Person.type)  # 可以通过类对象获取类属性

# 可以通过实例对象来获取类属性
print(p1.type)
print(p2.type)

p1.type = 'human'
print(p1.type)  # 并不会修改类属性,而是给实例对象添加了一个新的对象属性

# 类属性只能通过类对象来修改,实例对象无法修改类属性
Person.type = 'monkey'  # 修改了类属性
print(p2.type)   # monkey
print(p1.type)   # human

07-私有属性的使用

import datetime


class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.__money = 1000  # 以两个下划线开始的变量是私有变量

    def get_money(self):
        print('{}查询了余额'.format(datetime.datetime.now()))
        return self.__money

    def set_money(self, qian):
        if type(qian) != int:
            print('设置的余额不合法')
            return
        print('修改余额了')
        self.__money = qian

    def __demo(self):  # 以两个下划线开始的函数,是私有函数,在外部无法调用
        print('我是demo函数,name={}'.format(self.name))

    def test(self):
        self.__demo()


p = Person('张三', 18)
print(p.name, p.age)  # 可以直接获取到
# print(p.__money)   # 不能够直接获取到私有变量
# p.__demo()  # 不能直接调用demo函数,它是私有方法
p._Person__demo()
# 获取私有变量的方式:
# 1. 使用 对象._类名__私有变量名获取
# print(p._Person__money)  # 通过这种方式也能获取到私有属性

# 2. 定义get和set方法来获取
print(p.get_money())
p.set_money('hello')
print(p.get_money())

# 3. 使用property来获取(有机会的话补充)

08-类方法和静态方法

class Person(object):
    type = 'human'

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

    def eat(self, food):  # 对象方法有一个参数self,指的是实例对象
        print(self.name + '正在吃' + food)

    # 如果一个方法里没有用到实例对象的任何属性,可以将这个方法成static
    @staticmethod
    def demo():
        print('hello')

    @classmethod
    def test(cls):  # 如果这个函数只用到了类属性,我们可以把定义成为一个类方法
        # 类方法会有一个参数 cls,也不需要手动的传参,会自动传参
        # cls 指的是类对象    cls is Person
        print(cls.type)
        print('yes')


p1 = Person('张三', 18)
# 实例对象在调用方法时,不需要给形参self传参,会自动的把实例对象传递给self

p2 = Person('李四', 19)

# eat 对象方法,可以直接使用实例对象.方法名(参数)调用
# 使用对象名.方法名(参数)调用的方式,不需要传递self
# 会自动将对象名传递给self
p1.eat('红烧牛肉泡面')  # 直接使用实例对象调用方法

# 对象方法还可以使用 类对象来调用类名.方法名()
# 这种方式,不会自动给self传参,需要手动的指定self
Person.eat(p2, '西红柿鸡蛋盖饭')

# print(p1.eat)
# print(p2.eat)
# print(Person.eat)

# 静态方法:没有用到实例对象的任何属性
Person.demo()
p1.demo()

# 类方法:可以使用实例对象和类对象调用
p1.test()
Person.test()

09-静态方法的使用

class Calculator(object):
    @staticmethod
    def add(a, b):
        return a + b

    @staticmethod
    def minus(a, b):
        return a - b

    @staticmethod
    def mul(a, b):
        return a * b


print(Calculator.add(2, 3))

10-单例设计模式

class Singleton:
    __instance = None  # 类属性
    __is_first = True

    @classmethod
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            # 申请内存,创建一个对象,并把对象的类型设置为cls
            cls.__instance = object.__new__(cls)

        return cls.__instance

    def __init__(self, a, b):
        if self.__is_first:
            self.a = a
            self.b = b
            self.__is_first = False


# 调用 __new__ 方法申请内存
# 如果不重写 __new__ 方法,会调用 object 的 __new__ 方法
# object的 __new__ 方法会申请内存
# 如果重写了 __new__ 方法,需要自己手动的申请内存
s1 = Singleton('呵呵', '嘿嘿嘿')
s2 = Singleton('哈哈', '嘻嘻嘻')
s3 = Singleton('嘎嘎', '嘤嘤嘤')

print(s1 is s2)  # True
print(s1.a, s1.b)

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老板来片烤面包

君子博学于文,赠之以礼,谢君~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值