函数的参数
- 关键字参数
根据参数名字来决定如何执行
def say_hello(**kwargs):
print(kwargs)
for key in kwargs:
print(key, '--->', kwargs[key])
if 'name' in kwargs:
print('你好, %s!' % kwargs['name'])
elif 'age' in kwargs:
age = kwargs['age']
if age <= 16:
print('你还是个小屁孩')
else:
print('你是一个成年人')
else:
print('请提供个人信息!')
- 命名关键字参数
参数里面加一个* ,后面的参数都要使用带名字传入的参数
def bar():
def foo(a, b, c, *, name, age):
print(a + b + c)
print(name, ':', age)
return foo
x = bar()
x(1, 2, 3, name='Hao', age=38)
函数的包装器
from random import randint
def record(fn):
def wrapper(*args, **kwargs):
print('准备执行%s函数' % fn.__name__) #可调函数的名字
print(args)
print(kwargs)
# 此行代码在执行被装饰的函数
# 在这行代码的前后我们可以附加其他的代码
# 这些代码可以让我们在执行函数时做一些额外的工作
val = fn(*args, **kwargs)
print('%s函数执行完成' % fn.__name__)
print('返回了%d' % val)
# 返回被装饰的函数的执行结果
return val
return wrapper
# 通过装饰器修饰f函数 让f函数在执行过程中可以做更多额外的操作
@record
def f(n):
if n == 0 or n == 1:
return 1
return n * f(n - 1)
@record
def add(x, y):
return x + y
if __name__ == '__main__':
print(add(x=1, y=2))
print(f(n=5))
#结果
准备执行add函数
()
{'x': 1, 'y': 2}
add函数执行完成
返回了3
3
准备执行mul函数
()
{'x': 3, 'y': 2}
mul函数执行完成
返回了6
6
准备执行f函数
()
{'n': 5}
准备执行f函数
(4,)
{}
准备执行f函数
(3,)
{}
准备执行f函数
(2,)
{}
准备执行f函数
(1,)
{}
f函数执行完成
返回了1
f函数执行完成
返回了2
f函数执行完成
返回了6
f函数执行完成
返回了24
f函数执行完成
返回了120
120
面向对象
- 继承
子类可以继承父类全部的属性和方法,子类还可以对父类的方法进行重写。(当子类里面没有定义属性或者方法时,直接调用父类的方法,如果子类重新定义了方法默认调用的是子类的方法) - 依赖
对象与对象之间的相互依赖 - 关联
对象与对象之间属于不能分割
from abc import ABCMeta, abstractmethod
from random import randint, randrange
class Fighter(object, metaclass=ABCMeta):
"""战斗者"""
# 通过__slots__魔法限定对象可以绑定的成员变量
__slots__ = ('_name', '_hp')
def __init__(self, name, hp):
"""
初始化方法
:param name: 名字
:param hp: 生命值
"""
self._name = name
self._hp = hp
@property
def name(self):
return self._name
@property
def hp(self):
return self._hp
@hp.setter
def hp(self, hp):
self._hp = hp if hp >= 0 else 0
@property
def alive(self):
return self._hp > 0
@abstractmethod
def attack(self, other):
"""
攻击
:param other: 被攻击的对象
"""
pass
class Ultraman(Fighter):
"""奥特曼"""
__slots__ = ('_name', '_hp', '_mp')
def __init__(self, name, hp, mp):
"""
初始化方法
:param name: 名字
:param hp: 生命值
:param mp: 魔法值
"""
super().__init__(name, hp)
self._mp = mp
def attack(self, other):
other.hp -= randint(15, 25)
def huge_attack(self, other):
"""
究极必杀技(打掉对方至少50点或四分之三的血)
:param other: 被攻击的对象
:return: 使用成功返回True否则返回False
"""
if self._mp >= 50:
self._mp -= 50
injury = other.hp * 3 // 4
injury = injury if injury >= 50 else 50
other.hp -= injury
return True
else:
self.attack(other)
return False
def magic_attack(self, others):
"""
魔法攻击
:param others: 被攻击的群体
:return: 使用魔法成功返回True否则返回False
"""
if self._mp >= 20:
self._mp -= 20
for temp in others:
if temp.alive:
temp.hp -= randint(10, 15)
return True
else:
return False
def resume(self):
"""恢复魔法值"""
incr_point = randint(1, 10)
self._mp += incr_point
return incr_point
def __str__(self):
return '~~~%s奥特曼~~~\n' % self._name + \
'生命值: %d\n' % self._hp + \
'魔法值: %d\n' % self._mp
class Monster(Fighter):
"""小怪兽"""
__slots__ = ('_name', '_hp')
def attack(self, other):
other.hp -= randint(10, 20)
def __str__(self):
return '~~~%s小怪兽~~~\n' % self._name + \
'生命值: %d\n' % self._hp
def is_any_alive(monsters):
"""判断有没有小怪兽是活着的"""
for monster in monsters:
if monster.alive > 0:
return True
return False
def select_alive_one(monsters):
"""选中一只活着的小怪兽"""
monsters_len = len(monsters)
while True:
index = randrange(monsters_len)
monster = monsters[index]
if monster.alive > 0:
return monster
def display_info(ultraman, monsters):
"""显示奥特曼和小怪兽的信息"""
print(ultraman)
for monster in monsters:
print(monster, end='')
def main():
u = Ultraman('骆昊', 1000, 120)
m1 = Monster('舒小玲', 250)
m2 = Monster('白元芳', 500)
m3 = Monster('王大锤', 750)
ms = [m1, m2, m3]
fight_round = 1
while u.alive and is_any_alive(ms):
print('========第%02d回合========' % fight_round)
m = select_alive_one(ms) # 选中一只小怪兽
skill = randint(1, 10) # 通过随机数选择使用哪种技能
if skill <= 6: # 60%的概率使用普通攻击
print('%s使用普通攻击打了%s.' % (u.name, m.name))
u.attack(m)
print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))
elif skill <= 9: # 30%的概率使用魔法攻击(可能因魔法值不足而失败)
if u.magic_attack(ms):
print('%s使用了魔法攻击.' % u.name)
else:
print('%s使用魔法失败.' % u.name)
else: # 10%的概率使用究极必杀技(如果魔法值不足则使用普通攻击)
if u.huge_attack(m):
print('%s使用究极必杀技虐了%s.' % (u.name, m.name))
else:
print('%s使用普通攻击打了%s.' % (u.name, m.name))
print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))
if m.alive > 0: # 如果选中的小怪兽没有死就回击奥特曼
print('%s回击了%s.' % (m.name, u.name))
m.attack(u)
display_info(u, ms) # 每个回合结束后显示奥特曼和小怪兽的信息
fight_round += 1
print('\n========战斗结束!========\n')
if u.alive > 0:
print('%s奥特曼胜利!' % u.name)
else:
print('小怪兽胜利!')
if __name__ == '__main__':
main()
- 类的静态调用方法
#求三角形的周长和面积
from math import sqrt
class Triangle(object):
def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c
# @classmethod
# def is_valid(cls, a, b, c):
@staticmethod #类的静态的调用,当不需要对象且又是属于类必要的要求
def is_valid(a, b, c):
# print(cls)
# print(type(cls))
return a + b > c and b + c > a and a + c > b
def perimeter(self):
return self._a + self._b + self._c
def area(self):
half = self.perimeter() / 2
return sqrt(half * (half - self._a) *
(half - self._b) * (half - self._c))
def main():
a = 3
b = 4
c = 5
if Triangle.is_valid(a, b, c):
t = Triangle(a, b, c)
print(t.perimeter())
print(Triangle.perimeter(t))
print(t.area())
print(Triangle.area(t))
else:
print('无法构成三角形.')
if __name__ == '__main__':
main()
- 定义抽象类(不能拿来创建对象,只能继承),抽象类里的方法加入包装器@abstractmeshod必须需要子类的重写
# Python没有从语言层面支持抽象类的概念
# 我们可以通过abc模块来制造抽象类的效果
# 在定义类的时候通过指定metaclass=ABCMeta可以将类声明为抽象类
# 抽象类是不能创建对象的 抽象类存在的意义是专门拿给其他类继承
# abc模块中还有一个包装器abstractmethod
# 通过这个包装器可以将方法包装为抽象方法 必须要求子类进行重写
from abc import ABCMeta, abstractmethod
class Employee(object, metaclass=ABCMeta):
"""员工"""
def __init__(self, name):
"""
初始化方法
:param name: 姓名
"""
self._name = name
@property
def name(self):
return self._name
@abstractmethod
def get_salary(self):
"""
获得月薪
:return: 月薪
"""
pass
class Manager(Employee):
"""部门经理"""
def get_salary(self):
return 15000.0
class Programmer(Employee):
"""程序员"""
def __init__(self, name, working_hour=0):
super().__init__(name)
self._working_hour = working_hour
@property
def working_hour(self):
return self._working_hour
@working_hour.setter
def working_hour(self, working_hour):
self._working_hour = working_hour \
if working_hour > 0 else 0
def get_salary(self):
return 150.0 * self._working_hour
class Salesman(Employee):
"""销售员"""
def __init__(self, name, sales=0):
super().__init__(name)
self._sales = sales
@property
def sales(self):
return self._sales
@sales.setter
def sales(self, sales):
self._sales = sales if sales > 0 else 0
def get_salary(self):
return 1200.0 + self._sales * 0.05
def main():
emps = [
Manager('刘备'), Programmer('诸葛亮'),
Manager('曹操'), Salesman('荀彧'),
Salesman('吕布'), Programmer('张辽'),
Programmer('赵云')
]
for emp in emps:
if isinstance(emp, Programmer): #判断某一个对象是不是属于某一类
emp.working_hour = int(input('请输入%s本月工作时间: ' % emp.name))
elif isinstance(emp, Salesman):
emp.sales = float(input('请输入%s本月销售额: ' % emp.name))
# 同样是接收get_salary这个消息 但是不同的员工表现出了不同的行为
# 因为三个子类都重写了get_salary方法 所以这个方法会表现出多态行为
print('%s本月工资为: ¥%s元' %
(emp.name, emp.get_salary()))
if __name__ == '__main__':
main()
#分数运算(对象返回自己本身)
from math import gcd
class Fraction(object):
def __init__(self, num, den):
if den == 0:
raise ValueError('分母不能为0')
self._num = num
self._den = den
# self.normalize()
# self.simplify()
@property
def num(self):
return self._num
@property
def den(self):
return self._den
def add(self, other):
return Fraction(self._num * other.den + self._den * other.num,
self._den * other.den).simplify().normalize()
def sub(self, other):
return Fraction(self._num * other.den - self._den * other.num,
self._den * other.den).simplify().normalize()
def mul(self, other):
return Fraction(self._num * other.num, self._den * other.den)\
.simplify().normalize()
def div(self, other):
return Fraction(self._num * other.den, self._den * other.num)\
.simplify().normalize()
def __add__(self, other):
return self.add(other)
def __sub__(self, other):
return self.sub(other)
def __mul__(self, other):
return self.mul(other)
def __truediv__(self, other):
return self.div(other)
def simplify(self):
if self._num != 0 and self._den != 1:
factor = gcd(abs(self._num), abs(self._den))
if factor > 1:
self._num //= factor
self._den //= factor
return self
def normalize(self):
if self._den < 0:
self._num = -self._num
self._den = -self._den
return self
def __str__(self):
if self._num == 0:
return '0'
elif self._den == 1:
return str(self._num)
else:
return '%d/%d' % (self._num, self._den)
def main():
f1 = Fraction(3, -6)
f2 = Fraction(3, 4)
print(f1)
print(f2)
print(f1 + f2)
print(f1 - f2)
print(f1 * f2)
print(f1 / f2)
print((f1 - f2) * f2)
if __name__ == '__main__':
main()
- 面向对象做游戏
from random import randrange
class Card(object):
"""一张牌"""
def __init__(self, suite, face):
self._suite = suite
self._face = face
@property
def face(self):
return self._face
@property
def suite(self):
return self._suite
def __str__(self):
if self._face == 1:
face_str = 'A'
elif self._face == 11:
face_str = 'J'
elif self._face == 12:
face_str = 'Q'
elif self._face == 13:
face_str = 'K'
else:
face_str = str(self._face)
return '%s%s' % (self._suite, face_str)
class Poker(object):
"""一副牌"""
def __init__(self):
self._cards = []
self._current = 0
for suite in '♠♥♣♦':
for face in range(1, 14):
card = Card(suite, face)
self._cards.append(card)
@property
def cards(self):
return self._cards
def shuffle(self):
"""洗牌"""
self._current = 0
cards_len = len(self._cards)
for index in range(cards_len):
pos = randrange(cards_len)
self._cards[index], self._cards[pos] = \
self._cards[pos], self._cards[index]
@property
def next(self):
"""发牌"""
card = self._cards[self._current]
self._current += 1
return card
@property
def has_next(self):
"""还有没有牌"""
return self._current < len(self._cards)
class Player(object):
def __init__(self, name):
self._name = name
self._cards_on_hand = []
@property
def name(self):
return self._name
@property
def cards_on_hand(self):
return self._cards_on_hand
def get(self, card):
"""摸牌"""
self._cards_on_hand.append(card)
def arrange(self):
"""玩家整理手上的牌"""
self._cards_on_hand.sort(key=get_face)
def get_suite(card):
return card.suite
def get_face(card):
return card.face
def main():
p = Poker()
p.shuffle()
players = [Player('东邪'), Player('西毒'), Player('南帝'), Player('北丐')]
for _ in range(13):
for player in players:
player.get(p.next)
for player in players:
print(player.name + ':', end=' ')
player.arrange()
for card in player.cards_on_hand:
print(card, end=' ')
print()
if __name__ == '__main__':
main()
-面向对象和pygame 结合使用编写小游戏
# 五子棋
import pygame
EMPTY = 0
BLACK = 1
WHITE = 2
black_color = [0, 0, 0]
white_color = [255, 255, 255]
class RenjuBoard(object):
def __init__(self):
self._board = [[]] * 15
self.reset()
def reset(self):
for row in range(len(self._board)):
self._board[row] = [EMPTY] * 15
def move(self, row, col, is_black)
if self._board[row][col] == EMPTY:
self._board[row][col] = BLACK if is_black else WHITE
return True
return False
def draw(self, screen):
for index in range(1, 16):
pygame.draw.line(screen, black_color,
[40, 40 * index], [600, 40 * index], 1)
pygame.draw.line(screen, black_color,
[40 * index, 40], [40 * index, 600], 1)
pygame.draw.rect(screen, black_color, [36, 36, 568, 568], 4)
pygame.draw.circle(screen, black_color, [320, 320], 5, 0)
pygame.draw.circle(screen, black_color, [160, 160], 5, 0)
pygame.draw.circle(screen, black_color, [480, 480], 5, 0)
pygame.draw.circle(screen, black_color, [480, 160], 5, 0)
pygame.draw.circle(screen, black_color, [160, 480], 5, 0)
for row in range(len(self._board)):
for col in range(len(self._board[row])):
if self._board[row][col] != EMPTY:
ccolor = black_color \
if self._board[row][col] == BLACK else white_color
pos = [40 * (col + 1), 40 * (row + 1)]
pygame.draw.circle(screen, ccolor, pos, 20, 0)
def main():
board = RenjuBoard()
is_black = True
pygame.init()
pygame.display.set_caption('五子棋')
screen = pygame.display.set_mode([640, 640])
screen.fill([255, 255, 0])
board.draw(screen)
pygame.display.flip()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYUP:
pass
elif event.type == pygame.MOUSEBUTTONDOWN\
and event.button == 1:
x, y = event.pos
row = round((y - 40) / 40)
col = round((x - 40) / 40)
if board.move(row, col, is_black):
is_black = not is_black
screen.fill([255, 255, 0])
board.draw(screen)
pygame.display.flip()
pygame.quit()
if __name__ == '__main__':
main()
大球小球游戏
from random import randint
import pygame
class Ball(object):
def __init__(self, center, color, radius, speed):
self._center = center
self._color = color
self._radius = radius
self._speed = speed
@property
def center(self):
return self._center
@property
def radius(self):
return self._radius
def move(self):
x, y = self._center[0], self._center[1]
sx, sy = self._speed[0], self._speed[1]
self._center = x, y = x + sx, y + sy
if x + self._radius >= 800 or x - self._radius <= 0:
self._speed = -sx, sy
if y + self._radius >= 600 or y - self._radius <= 0:
self._speed = sx, -sy
def eat(self, other):
pass
def draw(self, screen):
pygame.draw.circle(screen, self._color, self._center,
self._radius, 0)
def main():
balls = []
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('大球吃小球')
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN \
and event.button == 1:
color = random_color()
radius = randint(10, 100)
speed = randint(-10, 10), randint(-10, 10)
ball = Ball(event.pos, color, radius, speed)
balls.append(ball)
refresh(screen, balls)
clock.tick(24)
for ball in balls:
ball.move()
pygame.quit()
def refresh(screen, balls):
bg_color = (242, 242, 242)
screen.fill(bg_color)
for ball in balls:
ball.draw(screen)
pygame.display.flip()
def random_color():
red = randint(0, 255)
green = randint(0, 255)
blue = randint(0, 255)
return red, green, blue
if __name__ == '__main__':
main()
#贪吃蛇
from abc import ABCMeta, abstractmethod
from random import randint
import pygame
BLACK_COLOR = (0, 0, 0)
GREEN_COLOR = (0, 255, 0)
FOOD_COLOR = (230, 185, 185)
UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3
class GameObject(object, metaclass=ABCMeta):
def __init__(self, x=0, y=0, color=BLACK_COLOR):
self._x = x
self._y = y
self._color = color
@property
def x(self):
return self._x
@property
def y(self):
return self._y
@abstractmethod
def draw(self, screen):
pass
class Wall(GameObject):
def __init__(self, x, y, width, height, color=BLACK_COLOR):
super().__init__(x, y, color)
self._width = width
self._height = height
@property
def width(self):
return self._width
@property
def height(self):
return self._height
def draw(self, screen):
pygame.draw.rect(screen, self._color,
(self._x, self._y, self._width, self._height), 4)
class Food(GameObject):
def __init__(self, x, y, size, color=FOOD_COLOR):
super().__init__(x, y, color)
self._size = size
self._hidden = False
def draw(self, screen):
if not self._hidden:
pygame.draw.circle(screen, self._color,
(self._x + self._size // 2, self._y + self._size // 2),
self._size // 2, 0)
self._hidden = not self._hidden
class SnakeNode(GameObject):
def __init__(self, x, y, size, color=GREEN_COLOR):
super().__init__(x, y, color)
self._size = size
@property
def size(self):
return self._size
def draw(self, screen):
pygame.draw.rect(screen, self._color,
(self._x, self._y, self._size, self._size), 0)
pygame.draw.rect(screen, BLACK_COLOR,
(self._x, self._y, self._size, self._size), 1)
class Snake(GameObject):
def __init__(self):
super().__init__()
self._dir = LEFT
self._nodes = []
self._alive = True
for index in range(5):
node = SnakeNode(290 + index * 20, 290, 20)
self._nodes.append(node)
@property
def dir(self):
return self._dir
@property
def alive(self):
return self._alive
@property
def head(self):
return self._nodes[0]
def change_dir(self, new_dir):
if (self._dir + new_dir) % 2 != 0:
self._dir = new_dir
def move(self):
if self._alive:
snake_dir = self._dir
x, y, size = self.head.x, self.head.y, self.head.size
if snake_dir == UP:
y -= size
elif snake_dir == RIGHT:
x += size
elif snake_dir == DOWN:
y += size
else:
x -= size
new_head = SnakeNode(x, y, size)
self._nodes.insert(0, new_head)
self._nodes.pop()
def collide(self, wall):
"""
撞墙
:param wall: 围墙
"""
head = self.head
if head.x < wall.x or head.x + head.size > wall.x + wall.width \
or head.y < wall.y or head.y + head.size > wall.y + wall.height:
self._alive = False
def eat_food(self, food):
if self.head.x == food.x and self.head.y == food.y:
tail = self._nodes[-1]
self._nodes.append(tail)
return True
return False
def eat_me(self):
pass
def draw(self, screen):
for node in self._nodes:
node.draw(screen)
def main():
def refresh():
"""刷新游戏窗口"""
screen.fill((242, 242, 242))
wall.draw(screen)
food.draw(screen)
snake.draw(screen)
pygame.display.flip()
def handle_key_event(key_event):
"""处理按键事件"""
key = key_event.key
if key == pygame.K_F2:
reset_game()
else:
if snake.alive:
new_dir = snake.dir
if key == pygame.K_w:
new_dir = UP
elif key == pygame.K_d:
new_dir = RIGHT
elif key == pygame.K_s:
new_dir = DOWN
elif key == pygame.K_a:
new_dir = LEFT
if new_dir != snake.dir:
snake.change_dir(new_dir)
def create_food():
row = randint(0, 29)
col = randint(0, 29)
return Food(10 + 20 * col, 10 + 20 * row, 20)
def reset_game():
nonlocal food, snake
food = create_food()
snake = Snake()
wall = Wall(10, 10, 600, 600)
food = create_food()
snake = Snake()
pygame.init()
screen = pygame.display.set_mode((620, 620))
pygame.display.set_caption('贪吃蛇')
screen.fill((242, 242, 242))
pygame.display.flip()
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
handle_key_event(event)
if snake.alive:
refresh()
clock.tick(10)
if snake.alive:
snake.move()
snake.collide(wall)
if snake.eat_food(food):
food = create_food()
pygame.quit()
if __name__ == '__main__':
main()
文件读写
- 文件遵循try -- except(可以有多个)--else--finally步骤
import requests
import json
def main():
# request / response
resp = requests.get('http://api.tianapi.com/meinv/?key=a78efafa3bb9d348860c2f7c962adc78&num=10')
mydict = json.loads(resp.text)
for tempdict in mydict['newslist']:
pic_url = tempdict['picUrl']
resp = requests.get(pic_url)
filename = pic_url[pic_url.rfind('/') + 1:]
try:
with open(filename, 'wb') as fs: #离开with自动释放关闭文件
fs.write(resp.content)
except IOError as e:
print(e)
if __name__ == '__main__':
main()