目录
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)