面向对象和json
1.属性
1.属性
- 定义类就是用代码描述清楚这个类是拥有哪些相同功能和哪些相同属性的对象的集合
- 方法(函数)用来描述相同功能
- 属性(变量)用来描述相同属性
属性分为两种:类属性(字段)、对象属性
- 类属性
- 怎么定义:直接定义在类中的变量就是类属性
- 怎么使用:通过 ‘类.’ 的方式去使用
- 什么时候用:如果属性值不会因为对象不同而不一样的时候
- 对象属性
- 怎么定义:以 ‘self.属性名 = 值’ 的方式定义在__init__方法中
- 怎么使用:通过 ‘对象.’ 的方式去使用
- 什么时候用:如果属性值会因为对象不同而不一样的时候
class Student:
# a是类属性
a = 10
# name和age是对象属性
def __init__(self):
self.name = '小明'
self.age = 18
print(Student.a)
Student.a = 200
print(Student.a)
stu = Student()
print(stu.name, stu.age)
# 练习:定义一个圆类,用有两个属性分别是半径和圆周率
class Circle:
pi = 3.1415926
def __init__(self):
self.radius = 0
def get_area(self):
return Circle.pi * self.radius ** 2
2.对象属性默认值
- 赋一个固定的值:每次创建对象的时候不能重新赋值,只能在创建好对象以后修改属性的值
- 使用没有默认值的参数赋值
- 使用有默认值的参数赋值
class Person:
def __init__(self, name, age=18, gender='男'):
self.name = name
self.age = age
self.gender = gender
self.height = 170
def __repr__(self):
# return f'<name:{self.name}, age:{self.age}, gender:{self.gender}>'
return str(self.__dict__)
p1 = Person('小明')
p2 = Person('张三', 20)
p3 = Person('小花', 22, '女')
print(p1)
print(p2)
print(p3)
3.self的使用
self是谁调用就指向谁,所以在对象中可以直接将self当成对象来使用。(这个类的对象能做的事情self都可以做)
class Rect:
def __init__(self, w, l):
self.width = w
self.length = l
# self.area = w * l
def get_area(self):
# self = r1; self = r2
return self.width * self.length # return r1.width * r1*length; r2.with * r2.length
def get_perimeter(self):
return (self.width + self.length) * 2
r1 = Rect(10, 20)
r2 = Rect(10, 5)
print(r1.get_area()) #200
print(r2.get_area()) #50
r3 = Rect(10, 10)
# print(r3.area)
print(r3.get_area()) #100
r3.width = 3
# print(r3.area)
print(r3.get_area()) #30
4.方法的选择
- 对象方法:如果实现函数的功能需要对象(需要对象属性)就使用对象方法
- 类方法:实现函数的功能不需要对象(或者对象属性)的前提下,需要类就使用类方法
- 静态方法:既不需要类,也不需要对象
2.继承
1.继承
-
继承就是让子类直接拥有父类所有的属性和方法
- 子类 - 继承者
- 父类(超类) - 被继承者
-
语法:
class 类名(父类列表): 类的说明文档 类的内容
-
注意:如果定义类的时候没有写父类,那么这个类默认继承Python的基类-object
class Person:
count = 61
def __init__(self):
self.name = '小明'
self.age = 18
self.gender = '男'
def eat(self):
print('吃饭')
def sleep(self):
print('睡觉')
class Student(Person):
pass
print(Student.count) #61
stu = Student()
print(stu.name, stu.age, stu.gender) #小明 18 男
stu.eat() #吃饭
stu.sleep() #睡觉
class A:
x = 10
def __init__(self):
self.y = 100
def func1(self):
print('func1')
@classmethod
def func2(cls):
print('func2')
@staticmethod
def func3():
print('func3')
class B(A):
pass
print(B.x) #10
b = B()
print(b.y) #100
b.func1() #func1
B.func2() #func2
B.func3() #func3
2.在子类中添加内容
-
添加类属性和方法
直接在子类中定义新的类属性和新的方法
-
添加对象属性
class C:
a = 10
def func1(self):
print('对象方法func1')
def __init__(self):
print('c的init')
self.m = 100
self.n = 200
class D(C):
# 新增类属性(字段)
x = 20
y = 30
# 新增方法
def func2(self):
print('对象方法2')
@classmethod
def func3(cls):
print('类方法')
def __init__(self):
# 在这儿调用父类的__init__方法就可以继承父类的对象属性
super().__init__() # 调用当前类的父类的__init__()
self.t = 500
print(D.a)
print(D.x, D.y)
d = D()
d.func1()
d.func2()
D.func3()
print(d.m, d.n)
print(d.t)
#10
#20 30
#c的init
#对象方法func1
#对象方法2
#类方法
#100 200
#500
class Animal:
def __init__(self, age, gender='雌'):
self.age = age
self.gender = gender
class Dog(Animal):
def __init__(self, name, breed='土狗', age=3, gender='雄'):
super().__init__(age, gender)
self.name = name
self.breed = breed
def __repr__(self):
return str(self.__dict__)
dog1 = Dog('大黄', breed='金毛')
dog2 = Dog('小白', '萨姆', 2)
print(dog1)
print(dog2)
#{'age': 3, 'gender': '雄', 'name': '大黄', 'breed': '金毛'}
#{'age': 2, 'gender': '雄', 'name': '小白', 'breed': '萨姆'}
3.多继承可以继承所有父类的所有的方法和类属性,只能继承第一个父类的对象属性 (了解)
class E:
a1 = 100
def __init__(self):
self.x1 = 100
self.x2 = 200
def func1(self):
print('E的func1')
class F:
b1 = 200
def __init__(self):
self.y1 = 'hello'
def func2(self):
print('F的func2')
class Test(E, F):
pass
print(Test.a1, Test.b1) #100 200
t1 = Test()
t1.func1() #E的func1
t1.func2() #F的func2
print(t1.x1, t1.x2) #100 200
print(t1.y1) # AttributeError: 'Test' object has no attribute 'y1'
3.json数据
1.json数据
json是一种通用的数据格式,主要用于不同语言之间进行有效的数据沟通
2.json数据格式
- 要求:
- 一个json有且只有一个数据;
- 唯一的这个数据必须是json支持的类型的数据
- json支持的类型:
- 数字 - 数字直接写,并且支持科学计数法,例如: 67、1.23、-23、23.8、3e5
- 字符串 - 只能使用双引号,支持转义字符,例如: “abc”、“abc\n123”、"\u4e00"
- 布尔值 - 只有 true 和 false 两个值
- 空值 - null
- 数组 - 相当于python的列表, [元素1, 元素2, …]
- 字典 - 相当于python的字典, 但是键只能是字符串
3.python数据和json数据的相互转换
json模块提供了python中所有和json操作相关的函数
-
json转Python:
json python 数字 int、float 字符串 str(双引号变单引号) 布尔值 true -> True; false -> False 空值 null -> None 数组 list 字典 dict json.loads(json格式字符串) - 将json格式字符串对应的json数据转换成相应的python数据 注:json格式字符串 - 指的是字符串内容是json的字符串
import json json.loads('"abc"') # 'abc' json.loads('100') # 100 json.loads('[10, 20, 30]') # [10, 20, 30] json.loads('{"a": 10, "10": 20}') # {'a': 10, '10': 20} result = json.loads('[10, "abc", true, null]') print(result) # [10, 'abc', True, None]
-
python转json:
python json int、float 数字 str 字符串,单引号会变成双引号 bool 布尔, True -> true, False -> false 列表、元组 数组 dict 字典,键会变成双引号字符串 None null json.dumps(python数据) - 将指定的Python数据转换成json格式字符串
json.dumps(100) # '100' json.dumps(True) # 'true' json.dumps(None) # 'null' json.dumps({10: 20, 'name': '小明', 'b': True}) # '{"10": 20, "name": "小明", "b": true}'
作业
-
定义一个狗类和一个人类:
狗拥有属性:姓名、性别和品种 拥有方法:叫唤
人类拥有属性:姓名、年龄、狗 拥有方法:遛狗
class Dog: def __init__(self, name, gender, breed): self.name = name self.gender = gender self.breed = breed def bark(self): print('叫唤') class Person: def __init__(self, name, age, dog): self.name = name self.age = age self.dog = dog def walk_dog(self): print('遛狗')
-
定义一个矩形类,拥有属性:长、宽 拥有方法:求周长、求面积
class Rectangle: def __init__(self, l, w): self.lenth = l self.width = w def get_perimeter(self): return 2 * (self.lenth + self.width) def get_areas(self): return self.lenth * self.width r1 = Rectangle(10, 8) r2 = Rectangle(25, 24) print(r1.get_perimeter(), r1.get_areas()) print(r2.get_perimeter(), r2.get_areas())
-
定义一个二维点类,拥有属性:x坐标、y坐标 拥有方法:求当前点到另外一个点的距离
class TwoDimensionPoint: def __init__(self, x, y): self.x_coordinate = x self.y_coordinate = y def get_distance(self, x0=2, y0=1): return ((self.x_coordinate-x0)**2+(self.y_coordinate-y0)**2)**0.5 p1 = TwoDimensionPoint(3, 1) print(p1.get_distance(1, 1))
-
定义一个圆类,拥有属性:半径、圆心 拥有方法:求圆的周长和面积、判断当前圆和另一个圆是否外切
class Circle: pi = 3.1415926 def __init__(self, radius, x, y): self.radius = radius self.x_coordinate = x self.y_coordinate = y def get_perimeter(self): return 2*Circle.pi*self.radius def get_areas(self): return Circle.pi*self.radius**2 def get_distance(self, x0=0, y0=0, radius=1): return ((self.x_coordinate-x0)**2+(self.y_coordinate-y0)**2)**0.5 == radius + self.radius c1 = Circle(3, 0, 0) print(c1.get_perimeter(), c1.get_areas()) print(c1.get_distance()) c2 = Circle(1,0,0) print(c2.get_distance(2, 0, 1))
-
定义一个线段类,拥有属性:起点和终点, 拥有方法:获取线段的长度
class Segment: def __init__(self, origin: tuple, terminus: tuple): self.origin = origin self.terminus = terminus def get_length(self): return ((self.origin[0]-self.terminus[0])**2+(self.origin[-1]-self.terminus[-1])**2)**0.5 s1 = Segment((1,1), (3,2)) print(s1.get_length())
-
取出英雄联盟网站所有英雄和价格
result = json.loads(open('file/英雄联盟.json', 'r', encoding='utf-8').read()) for x in result['hero']: print(x['name'], x['goldPrice'])