目录
01-练习
# 定义一个类属性,记录通过这个类创建了多少个对象
class Person(object):
__count = 0 # 类属性
def __new__(cls, *args, **kwargs):
cls.__count += 1
# 申请内存,创建一个对象,并设置类型是 Person 类
return object.__new__(cls)
def __init__(self, name, age):
# Person.count += 1
self.name = name
self.age = age
@classmethod
def get_count(cls):
return cls.__count
# 每次创建对象,都会调用 __new__ 和 __init__ 方法
# 调用 __new__ 方法,用来申请内存
# 如果不重写 __new__ 方法,它会自动找 object 的 __new__
# object的 __new__ 方法,默认实现是申请了一段内存,创建一个对象
p1 = Person('张三', 18)
p2 = Person('李四', 19)
p3 = Person('jack', 20)
print(p1, p2, p3)
print(Person.get_count())
# 申请了内存,创建了一个对象,被设置它的类型是Person
# p4 = object.__new__(Person)
# p4.__init__('tony', 23)
# print(p4)
02-面对对象的三大特征
# 面向对象编程有三大特性: 封装、继承和多态
# 封装: 函数是对语句的封装;类是对函数和变量的封装
# 继承: 类和类之间可以认为手动的建立父子关系,父类的属性和方法,子类可以使用
# 多态: 是一种技巧,提高代码的灵活度
# 一个一个的语句
def test():
a = 23 # 赋值语句
a += 3 # 算数运算符表达式语句
print('hello')
print('good')
class Person(object):
type = '人类'
def __init__(self):
pass
def eat(self):
pass
# 面向对象编程有三大特性: 封装、继承和多态 # 封装: 函数是对语句的封装;类是对函数和变量的封装 # 继承: 类和类之间可以认为手动的建立父子关系,父类的属性和方法,子类可以使用 # 多态: 是一种技巧,提高代码的灵活度
03-继承的使用
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('大黄', 3)
print(d1.name) # 父类里定义的属性,子类可以直接使用
d1.sleep() # 父类的方法子类实例对象可以直接调用
d1.bark()
s1 = Student('小明', 18)
s1.sleep()
s1.study()
# s1.bark()
04-Python里的继承特点
class A(object):
def demo_a(self):
print('我是A类里的方法demo_a')
def foo(self):
print('我是A类里的foo方法')
class B(object):
def demo_b(self):
print('我是B类里的方法demo_b')
def foo(self):
print('我是B类里的foo方法')
# Python里允许多继承
class C(A, B):
pass
c = C()
c.demo_a()
c.demo_b()
# 如果两个不同的父类有同名方法,有一个类属性可以查看方法的调用顺序
c.foo()
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
# 如果两个不同的父类有同名方法,有一个类属性可以查看方法的调用顺序 c.foo() print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
05-__mro__属性
class A(object):
pass
class B(object):
def foo(self):
print('我是B类里的foo方法')
class C(A):
def foo(self):
print('我是C类里的foo方法')
class D(B):
pass
class E(object):
pass
class X(C, D, E):
pass
x = X()
x.foo()
print(X.__mro__)
类属性可以查看方法的调用顺序
06-类方法和静态方法
class Person(object):
type = 'human'
def __init__(self, name, age):
self.name = name
self.age = age
# 这个方法要打印 name 属性
def demo(self):
print('姓名是', self.name)
# 这个方法需要访问到类属性 type
@classmethod
def bar(cls):
# print(cls is Person)
print(cls.type)
# 这个方法只需要打印 hello world
@staticmethod
def foo():
print('hello world')
p = Person('zhangsan', 19)
p.demo() # 实例对象调用实例方法时,会自动将实例对象传递给self
Person.demo(p)
# 类方法可以使用类对象和实例对象调用
p.bar()
Person.bar()
07-私有属性的继承特点
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age
self.__money = 1000
def eat(self):
print(self.name + '正在吃东西')
def __test(self):
print('我是Animal类里的test方法')
class Person(Animal):
def __demo(self):
print('我是Person里的私有方法')
p = Person('张三', 18)
print(p.name)
p.eat()
p._Person__demo() # 自己类里定义的私有方法 对象名._类名__私有方法名()
p._Animal__test() # 可以通过 对象名._父类名__私有方法调用()
# 私有属性和方法,子类不会继承
# p._Person__test() # 父类的私有方法,子类没有继承
# print(p._Person__money)
print(p._Animal__money)
08-新式类和经典类
# -*- coding:utf8-*-
# 手动的指定Student类继承自object
class Student(object): # 兼容性问题
pass
# 没有指定Dog的父类,python3里默认继承自object
class Dog:
pass
# 新式类和经典类的概念:
# 1. 新式类:继承自 object 的类我们称之为新式类
# 2. 经典类:不继承自 object 的类
# 在python2里,如果不手动的指定一个类的父类是object,这个类就是一个经典类
# python3里不存在 经典类,都是新式类
s = Student()
d = Dog()
print(dir(s))
print(dir(d))
这里主要是Python2和Python3的区别讲解:
为面试做准备。。。。。。。。。(类似没啥大用,但是考试会考)
09-Python2和Python3的区别
# -*- coding:utf8 -*-
print('你好世界')
print 'hello'
# name = 'zhangsan'
# x = input('请输入一个段内容:')
# print x # str int
y = raw_input('请输入内容:')
print y
10-面向对象相关方法
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
class X(object):
pass
class Student(Person, X):
pass
p1 = Person('张三', 18)
p2 = Person('张三', 18)
s = Student('jack', 20)
# 获取两个对象的内存地址 id(p1) == id(p2)
print(p1 is p2) # is 身份运算符运算符是用来比较是否是同一个对象
# type(p1) # 其实获取的就是类对象
print(type(p1) == Person)
# s这个实例对象是否是由Student类创建的?
print(type(s) == Student)
print(type(s) == Person) # False
# isinstance 用来判断一个对象是否是由指定的类(或者父类)实例化出来的
print(isinstance(s, (Student, X))) # True
print(isinstance(s, Person)) # True
print(isinstance(p1, Person)) # True
print(isinstance(p1, Student)) # False
# issubclass 用来判断一个类是否是另一个类的子类
print(issubclass(Student, (Person, X))) # True
print(issubclass(Person, Student)) # False
11-子类重写父类
# 继承特点:如果一个类A继承自类B,由类A创建出来的实例对象都能直接使用类B里定义的方法
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def sleep(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)
self.school = school
def sleep(self):
print(self.name + '正在课间休息时睡觉')
def study(self):
print(self.name + '正在学习')
s = Student('jerry', 20, '春田花花幼稚园') # 调用了父类的 __init__ 方法
s.sleep() # 调用了父类的 sleep方法
print(Student.__mro__)
# 1. 子类的实现和父类的实现完全不一样,子类可以选择重写父类的方法。
# 2. 子类在父类的基础上又有更多的实现
12-不使用多态
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):
self.name = name
self.dog = None
def work_with_pd(self):
if self.dog is not None:
self.dog.attack_enemy()
def work_with_bd(self):
if self.dog is not None:
self.dog.lead_road()
def work_with_dd(self):
if self.dog is not None:
self.dog.search_drug()
p = Person('张三')
pd = PoliceDog()
p.dog = pd
p.work_with_pd()
bd = BlindDog()
p.dog = bd
p.work_with_bd()
dd = DrugDog()
p.dog = dd
p.work_with_dd()
13-多态的使用
# 多态是基于继承,通过子类重写父类的方法,达到不同的子类对象调用相同的父类方法,得到不同的结果,提高代码的灵活度
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()
p = Person('张三')
pd = PoliceDog()
p.dog = pd
p.work_with_dog()
bd = BlindDog()
p.dog = bd
p.work_with_dog()
dd = DrugDog()
p.dog = dd
p.work_with_dog()
14-打开文件
从这里开始讲的是python打开文件了
# python 里使用 open 内置函数打开并操作一个文件
# open 参数介绍
# file:用来指定打开的文件(不是文件的名字,而是文件的路径)
# mode:打开文件时的模式,默认是 r 表示只读。
# encoding:打开文件时的编码方式。
# open函数会有一个返回值,打开的文件对象
# xxx.txt 写入时,使用的utf8编码格式
# 在windows操作系统里,默认使用gbk编码格式打开文件
# 解决方案: 写入和读取使用相同的编码格式。
# file = open('xxx.txt', encoding='utf8')
file = open('xxx.txt')
# print(type(file))
print(file.read())
file.close() # 操作完成文件以后,关闭文件
15-文件路径
# open 参数介绍
# file:用来指定打开的文件(不是文件的名字,而是文件的路径)
# mode:打开文件时的模式,默认是 r 表示只读。
# encoding:打开文件时的编码方式。
# import os
# print(os.name) # NT/posix
# windows系统里,文件夹之间使用 \ 分隔.
# 在非windows系统里,文件夹之间使用 / 分隔.
# os.sep
# 在Python的字符串里, \ 表示转义字符
# 路径书写的三种方式: 1. \\ 2. r'\' 3. '/'(推荐)
# 路径分为两种:
# 1. 绝对路径: 从电脑盘符开始的路径。
# file = open('C:\\Users\\chris\\Desktop\\Python基础\\Day13-文件操作\\01-代码\\xxx.txt')
# file = open(r'C:\Users\chris\Desktop\Python基础\Day13-文件操作\01-代码\xxx.txt')
# file = open('C:/Users/chris/Desktop/Python基础/Day13-文件操作/01-代码/xxx.txt')
# 2. 相对路径:当前文件所在的文件夹开始的路径。
# ../ 表示返回到上一级文件夹
# ./ 可以省略不写,表示当前文件夹
# / 不能随便用
file = open('xxx.txt')
# file = open('./demo/sss.txt')
# file = open('./../ppp.txt', encoding='utf8')
print(file.read())
file.close()
16-文件的打开方式
# mode 指的是文件的打开方式
# r:只读模式,默认,打开文件以后,只能读取,不能写入。如果文件不能存在,会报错
# w:写入模式,打开文件以后,只能写入,不能读取。如果文件存在,会覆盖文件;如果文件不存在,会创建文件。
# b:以二进制的形式打开文件,可以用来操作非文本文件。
# rb:以二进制读取 wb:以二进制写入
# a:追加模式,会在最后追加内容。如果文件不能存在,会创建文件;如果文件存在,会追加
# r+:可读写。如果文件不能存在,会报错
# w+:可读写。如果文件存在,会覆盖文件;如果文件不存在,会创建文件。
# file = open('xxx.txt', 'r')
# print(file.read())
# file.write('hello') 不能执行写入操作,会报错
# file = open('xs.txt', 'r') # 文件不存在时,会报错
# file = open('xxx.txt', 'w')
# file.read() # 不能够执行读取,会报错。
# file.write('hello') # 可以执行写入的操作
# file = open('yyy.txt', 'w')
# file = open('xxx.txt', 'rb')
# print(file.read()) # 读取的结果是二进制
# file = open('xxx.txt', 'wb')
# file.write('大家好才是真的好') # 报错,只能写入二进制
# file.write('大家好才是真的好'.encode('utf8'))
file = open('yyy.txt', 'w+')
file.write('哈哈哈')
file.seek(0, 0) # 写入之后,文件指针到最后,需要调用seek将文件指针重置到开头
print(file.read())
file.close()