# 练习
# 定义一个类属性 记录通过这个类创建了多少对象
class Person(object):
__count = 0 # 类属性
def __init__(self,name,age):
Person.__count += 1
self.name = name
self.age = age
@classmethod #
def get_count(cls):
return cls.__count
# 每次创建对象 都会调用__new__ __init__ f方法
p1 = Person('张三',18)
p2 = Person('李四',18)
p3 = Person('王五',18)
print(Person.get_count)
# 面向对象编程的三大特征:封装 继承 多态
# 封装:打包 函数是对语句的封装;类是对函数和变量的封装
# 继承:类和类之间可以手动的建立父子关系 父类的属性和方法 子类可以使用
# 多态:是一种技巧 提高代码的灵活度
# 继承的使用
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print(self.name + '在睡觉')
class Dog(object):
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print(self.name + '在睡觉')
def bark(self):
print(self.name + '正在叫')
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print(self.name + '在睡觉')
def study(self):
print(self.name + '爱学习')
# 把 Animal当作父类(基类)
# Dog Student 为子类(派生类)
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print(self.name + '在睡觉')
class Dog(Animal):
def bark(self):
print(self.name + '正在叫')
class Student(Animal):
def study(self):
print(self.name + '爱学习')
# Dog() 调用 __new__方法 在调用 __init__
# Dog() 里没有 __new__ 方法 会查看是否重写了 __new__ 方法
# 父类里也没有重写 __new__ 方法 会查找父类的父类 找到object
# 调用 __init__ 方法 Dog类没有实现 会自动找到Animal 父类
d1 = Dog('大黄',12)
print(d1.name)
d1.sleep()
s1 = Student('小帅',18)
s1.sleep()
s1.study()
# 子类可以使用父类下的方法
# 但Dog Student 两个之间的方法不能互相使用
# 继承的特点
class A(object):
def demo_a(self):
print('我是A类里的方法demo_a')
def foo(self):
print('我是A类里的方法foo_a')
class B(object):
def demo_b(self):
print('我是B类里的方法demo_b')
def foo(self):
print('我是B类里的方法foo_b')
# python 里允许多继承
class C(B,A): # 如果不写父类 python3 以后默认继承自object
pass
c = C()
c.demo_a()
c.demo_b()
c.foo() # 如果同名 class C(B,A) 按继承的顺序 谁在前 调用谁
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
# 如果有两个不同的父类有同名方法,有一个类属性可以查看方法的调用顺序
# __mro__ 属性
class A:
pass
class B:
def foo(self):
print('我是B类里的方法foo_b')
class C(A):
def foo(self):
print('我是C类里的方法foo_c')
class D(B):
pass
class E:
pass
class X(D,C,E):
pass
X().foo()
print(X.__mro__)
# 继承的传递
# 类方法和静态方法回顾
class Person:
type = 'human'
def __init__(self,name,age):
self.name = name
self.age = age
# 需要打印name
def demo(self):
print('姓名是',self.name)
# 需要访问到类属性
@classmethod
def bar(cls): # 不叫cls也行 self cls 都是临时指向
print(cls is Person) # cls === Person
print(cls.type)
# 只需要打印hello world
@staticmethod
def foo(): # 静态方法 什么都不用给
print('hello world')
p = Person('小帅',18)
p.demo() # 实例对象调用 将实例对象传递给self
Person.demo(p)
# 类方法可以使用类对象和实例对象调用
p.bar()
Person.bar()
# 要访问到实例对象的属性 实例方法
# 要访问到类对象的属性 类方法
# 什么都不访问 静态方法
# 私有属性的继承特点
class Animal:
def __init__(self,name,age):
self.name = name
self.age = age
self.__money = 1000
def eat(self):
print(self.name + '在吃东西')
def __test(self):
print('__test方法')
class Person(Animal):
def __demo(self):
print('__demo方法')
p = Person('小明',18)
print(p.name)
p.eat()
p._Person__demo()
# 自己类定义的私有方法 对象名._类名__私有方法名()
# p._Person__test() # 父类的私有方法 私有属性 子类没有继承
p._Animal__test() # 可以通过 对象名._父类名__私有方法名() 调用
print(p._Animal__money)
# 私有属性和方法 子类不会继承
# 子类没有 如果硬要调用 可以通过父类调用
# 新式类 和 经典类
# 手动指定Student类继承自object
class Student(object):
pass
# 没有指定Dog的父类 python3 里默认继承自object
class Dog:
pass
# 新式类和经典类的概念:
# 新式类:继承自object的类 我们称之为新式类
# 经典类:不继承object的类
# python 2 3 的区别
# python3 里不存在 经典类 都是新式类
# 在python2里 如果不手动指定一个类的父类是object 这个类就是一个经典类
# python 2 里默认不支持中文 要加一行
# -*- coding:utf8 -*-
# python3 默认支持中文
# print '22' # python2 里print可以这样写
print('20200814') # python3 统一这样写 不再支持2的写法
# input 有区别
# 2 会把用户的输入当作代码 根据用户输入的内容来确定类型 raw_input 相当于3的input
# 3 直接接收用户的输入 所有的类型都是字符串类型 不再支持 raw_input
# 面向对象的相关的方法
class Animal(object):
def __init__(self,name,age):
self.name = name
self.age = age
class X(object):
pass
class Student(Animal,X):
pass
p1 = Animal('张三',18)
p2 = Animal('张三',18)
s = Student('jack',18)
# 获取对象的内存地址 id(p1) id(p2)
print(p1 is p2) # is 运算符是用来比较是否是同一个对象
print(type(p1)) # 其实获取的就是类对象
print(type(p1) == Animal)
#print('p1是Animal类创建的实例对象')
# s 这个实例对象是否是由Student类创建的
print(type(s) == Student)# True
print(type(s) == Animal) # False
# ininstance 用来判断一个对象是否由指定的类(或者父类)实例化来的
print(isinstance(s,(Student,X))) # True 可以判断多个
print(isinstance(s,Animal)) # True
# issubclass 用来判断一个类是否是另一个类的子类
print(issubclass(Student,Animal))
# 子类重写父类方法
#
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print(self.name + '在吃东西')
class Student(Person):
def __init__(self,name,age,school):
# self.name = name
# self.age = age
# 子类在父类实现的基础上,又添加了自己的新的功能
# 调用父类方法的两种方式:
# 1.父类名.方法名(self,参数列表)
# Person.__init__(self.name.age)
# 2.使用super直接调用父类方法
super(Student,self).__init__(name,age)
# super().__init__(name,age) # super()里面可以不写
self.school = school
def eat(self):
print(self.name + '休息的时候在吃东西')
def study(self):
print(self.name + '在学习')
s = Student('小明',18,'清华小学')
s.eat()
s.study()
# 1. 子类的实现和父类的实现完全不一样 子类可以选择重写父类的方法
# 2. 子类在父类的基础上又有更多的实现
# 多态的使用
# 多态是基于继承,通过子类重写父类的方法,达到不同的子类对象调用相同的父类方法,得到不同的结果
# 提高代码灵活度
class PoliceDog(object):
def attack_enemy(self):
print('警犬在攻击坏人')
class BlindDog(object):
def lead_road(self):
print('导盲犬在引路 ')
class DrugDog(object):
def search_drug(self):
print('缉毒犬在搜索')
class Person(object):
def __init__(self,name,dog):
self.name = name
self.dog = dog
def work_with_pd(self):
print(self.name + '在工作')
self.dog.attack_enemy()
def work_with_bd(self):
print(self.name + '在工作')
self.dog.lead_road()
pd = PoliceDog()
police = Person('张警官',pd)
police.dog = pd
police.work_with_pd()
bd = BlindDog()
police = Person('张警官',pd)
police.dog = bd
police.work_with_bd()
# 经过多态之后
class Dog(object):
def work(self):
print('在工作')
class PoliceDog(Dog):
def work(self):
print('警犬在攻击坏人')
class BlindDog(Dog):
def work(self):
print('导盲犬在引路 ')
class DrugDog(Dog):
def work(self):
print('缉毒犬在搜索')
class Person(object):
def __init__(self,name):
self.name = name
self.dog = None
def work_with_dog(self):
if self.dog is not None and isinstance(self.dog,Dog):
# 不为空 且 为狗的类型
self.dog.work()
police = Person('张警官')
pd = PoliceDog()
police.dog = pd
police.work_with_dog()
bd = BlindDog()
police.dog = bd
police.work_with_dog()
dd = DrugDog()
police.dog = dd
police.work_with_dog()
# 简化了
# 文件的打开和关闭
# open 内置函数 打开并操作一个文件
# open 函数
# file:用来指定打开的文件 (路径)
# mode:打开文件时的模式 默认r 只读
# encoding:打开文件时的编码方式
# xxx.txt 写入时 使用的是utf8编码模式
# 在windows操作系统里,默认使用gbk编码格式打开文件
file = open('Z:\\翟少帅\\整理\\浮躁\\Python\\Notepad++配置Python开发环境.txt','r',encoding='utf8')
print(file.read()) # 读取内容
file.close() # 操作完文件以后 关闭文件
# 路径:绝对路径 相对路径
# . 当前目录 ../ 上级目录
# \ python 转义字符 所以要用\\ 或者前面加 r
file = open(r'Z:\翟少帅\整理\浮躁\Python\Notepad++配置Python开发环境.txt','r',encoding='utf8')
print(file.read()) # 读取内容
file.close() # 操作完文件以后 关闭文件
# 非wind系统 / 表示文件夹之间分隔 win \
import os
print(os.sep)
# 路径书写的三种方式 1.\\ 2.r'\' 3.'/' 建议第三种
file = open('Z:/翟少帅/整理/浮躁/Python/Notepad++配置Python开发环境.txt','r',encoding='utf8')
print(file.read()) # 读取内容
file.close() # 操作完文件以后 关闭文件
# 文件的打开方式
# r 只读模式 默认 打开文件以后 只能读取 不能写入 如果文件不存在 报错
# w 写入模式 打开文件以后 只能写入 不能读取 如果文件存在 会覆盖文件 如果文件不存在 则会新建
# b 以二进制的形式打开文件 非文本的内容 比如图片
# rb 以二进制读取 读取结果是二进制 wb:以二进制的形式写入文件
# a 追加模式 会在最后追加内容 如果文件不存在 会创建文件
# r+ 可读写 如果文件不存在 报错
# w+ 可读写 如果文件存在 会覆盖文件 如果文件不存在 则会新建
# 一般要么读 要么写 单一操作
import os
print(os.getcwd()) # 当前工作目录
file = open('./xxx.txt','w')
file.write('2020')
file.close()
file = open('./xxx.txt','wb')
file.write('2021'.encode('utf8'))
file.close()
file = open('./xxx.txt','r')
print(file.read())
file.close()
file = open('yyy.txt','w+')
file.write('哈哈哈哈')
file.seek(0,0) # 写入之后 文件指针到最后 需要调用seek 将文件指针重置到开头
print(file.read())
file.close()
# P181
又开始的python-day09-20200814-继承-类方法-文件的打开和关闭
最新推荐文章于 2024-11-04 21:51:40 发布