栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python-面向对象(3)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python-面向对象(3)

#内容概览

  • 派生方法的实战演练
  • 面向对象三大特性之封装
  • property伪装属性
  • 面向对象三大特性之封装
  • 面向对象之反射
  • 反射实战案例
    ###派生方法的实战演练
import datetime
import json

d = {
	'time1' : datetime.datetime.today(),
	'time2' : datetime.date.today()
}
res = json.dumps(d)
print(res)

"""
上述代码会直接报错:
raise TypeError(f'Object of type {o.__class__.__name__} '
    TypeError: Object of type datetime is not JSON serializable因为json序列化python对数据类型有限制
不是所有类型都能序列化
    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+
  	只有上面的数据类型才能够被序列化
"""
# 解决方案1:直接将不能序列化的数据类型转换成可以被序列化的数据类型

d = {
	'time1' : str(datetime.datetime.today()),
	'time2' : str(datetime.date.today())
}
res = json.dumps(d)
print(res)

# 解决方案2:使用派生方法

d = {
'time1' : datetime.datetime.today(),
'time2' : datetime.date.today()
}
res = json.dumps(d)
print(res)
"""
查看JSONEncoder源码发现序列化报错是由default方法触发的
如果想要避免报错,那么就需要使用派生方法对default方法做修改
"""
class MyJsonEncode(json.JSONEncoder):
	def default(self, o):
		if isinstance(o, datetime.datetime):  # 如果是datetime类型数据,格式化处理
			return o.strftime('%Y-%m-%d %H:%M:%S')
		elif isinstance(o, datetime.date):  # 如果是date类型数据,格式化处理
			return o.strftime('%Y-%m-%d')
		return super().default(o)  # 如果是可以序列化的类型,就直接使用原来的方法即可

res = json.dumps(d, cls=MyJsonEncode)
print(res)
json.dumps(d, cls=MyJsonEncode)

###面向对象三大特性之封装
封装其实就是将数据或功能隐藏起来,不能从外界轻易调用
但封装的目的不是让用户无法使用,而是给这些数据设定了一个接口,让用户通过接口才能使用到,我们在接口中添加一些额外的操作

"""
在类定义阶段,使用双下划线开头的名字,就是隐藏的属性,在当前类以外不能直接获取
在python中不会真正的限制任何代码,隐藏的属性只是经过了变形,其实还是可以访问到(__变量名>>>_类名__变量名),只不过这样做隐藏的意义也就没有了
"""
class Person(object):
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def check_info(self):  # 专门定义一个访问查看数据的接口
        print(f"""
			姓名:{self.__name}
			年龄:{self.__age}	
		""")

    def set_info(self, name, age):  # 定义一个修改数据的接口
        if len(name) == 0:
            print('用户名不能为空')
            return
        if not isinstance(age, int):
            print('年龄必须是数字')
            return
        self.__name = name
        self.__age = age


p1 = Person('jason', 20)
print(p1.__name)  # 'Person' object has no attribute '__name' 报错
p1.check_info()
p1.__age = 60  # 会新增一个属性
print(p1.__dict__)
p1.set_info('kevin', 30)
p1.check_info()

###property伪装属性
可以使方法的调用方式和属性相同(不用加括号就能调用方法)

class Myclass(object):
	def __init__(self, name):
		self.__name = name  # 将属性隐藏起来

	@property  # 将方法伪装成属性
	def name(self):
		return self.__name

	@name.setter  # 使伪装方法可以赋值修改
	def name(self, value):
		if not isinstance(value, str):
			raise TypeError(f'{value] must be str')
		self.__name = value

	@name.delter  # del伪装方法时执行
	def name(self):
		raise PermissionError('can not delete')

obj = Myclass('jason')
print(obj.name)
obj.name = 123  # 因为设置了只能修改为字符串,这里会主动抛错
del obj.name  # 主动抛错

###面向对象三大特性值多态
多态:一种事物的多种形态
一种事物有多种形态,但是相同的功能应该有相同的名字
这样的话,无论是什么形态,只要想调用同样的功能调用同一个名字即可

class Animal(object):
	def eat(self):
		pass

class Cat(Animal):
	def eat(self):
		print('猫吃饭')

class Dog(Animal):
	def eat(self):
		print('狗吃饭')

c1 = Cat()
d1 = Dog()
c1.eat()
d1.eat()

"""python也提供了强制性的操作"""
import abc
# 指定metaclass属性将类设置为抽象类,抽象类只为了限制子类,不能被实例化
class Animal(metaclass=abc.ABCMeta)
	@abc.abctractmethod  # 限制子类必须定义一个被这个装饰的方法
	def eat((self):
		pass

class Dog(Animal):
	def eat(self):  # 继承了Animal的子类都必须重写eat方法
		pass

"""
鸭子类型:
	只要你长得像鸭子,走路像鸭子,说话像鸭子,那么你就是鸭子
"""
class Teacher(object):
	def run(self):
		pass
	def eat(self):
		pass

class Student(object):
	def run(self):
		pass
	def eat(self):
		pass

###面向对象之反射

"""
反射:通过字符串来操作对象的数据或方法
反射主要有四个方法:
	hasattr():判断对象有没有字符串指定的属性或方法
	getattr():获取字符串指定的属性或方法
	setattr():根据字符串给对象设置属性
	delattr():根据字符串给对象删除属性
"""
class Myclass(object):
	name = '小明'
	def func(self):
		print('from func')

obj = Myclass()

print(hasattr(obj, 'name'))  # True 查询到属性或方法后返回True
res = getattr(obj, 'func')  # 获取对应名字的属性或方法,如果没有则报错
res()  # from func
setattr(obj, 'age', 18)
print(obj.age)  # 18
delattr(obj, 'age')
print(obj.__dict__)  # {}

###反射实战案例

class FtpServer:
	def serve_forever(self):
		while True:
			inp = inpput('input your cmd>>>:').strip()  # 获取用户输入
			com, file = inp.split()
			if hasattr(self, com):  # 判断输入的指令是否存在
				func = getattr(self, cmd)  # 获取对应的属性或方法
				func(file)
	def get(self, file):
		print(f'Downloading {file}...')

	def put(self, file):
		print(f'Uploading {file}...')

obj = FtpServer()
obj.serve_forever()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1029915.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号