目录
一切皆对象
类与对象
类的关键字是:class,所有类的基类是object,定义类的时候类的首字母一定要大写!
class Person(object):
'''定义一个人的类'''
country = 'china' #数据属性
def __init__(self, name, age):
self.name = name
self.age = age
if __name__ == '__main__':
person1= Person(name='xia', age=18) #person就是Person()实例化后的对象
person2= Person(name='夏', age=19) #person就是Person()实例化后的对象
print(person.__dict__) #将name='xia',age=18以字典的形式输出
print(person.__doc__) #输出'''定义一个人的类'''
数据属性和实例属性
数据属性:同一个类实例化后的不同的对象调用数据属性,内存地址都是一样的
person1.country和person2.country调用的内存地址是一样的
实例属性:如上栗子中在类里面定义的属性name,age被称为实例属性,定义的时候必须遵守函数的形参参数的规则,有几个参数就传几个
类的方法
在python类里边,编写的特性函数称为方法,共分为普通方法,特性方法,静态方法,类方法
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
# 普通方法
def show(self):
print("my name is {0} my age is {1}".format(self.name, self.age))
@property
def info(self): #不能有形式参数
print("........特性方法")
@staticmethod
def eat(): #没有self和cls参数
print("静态方法")
@classmethod #参数是cls
def driver(cls):
print("类方法")
if __name__ == '__main__':
person = Person(name='xia', age=18)
person.show()
person.info #特性方法的调用类似于调用类里的数据属性,后边不带()
Person.eat() #属于类,直接用类名调用
Person.driver() #属于类,直接用类名调用
类的继承
面向对象三大特性是:封装、继承、多态,一个类可以继承一个类,也可以继承多个类
子类可以继承父类所有的方法和属性
单继承:
#!/usr/bin/env python
# !coding:utf-8
class Person(object):
'''定义一个人的类'''
country = '中国'
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print("my name is {0} my age is {1}".format(self.name, self.age))
# 继承了Person类
class Worker(Person):
def __init__(self, name, age, salary):
super().__init__(name, age)
self.salary = salary
def info(self):
print("姓名{0} 年龄{1} 薪水{2}".format(self.name, self.age, self.salary))
# 如果子类没有show()方法,就会调用父类的show()方法,子类有的话直接重写show()方法
def show(self):
print("我是worker的show")
if __name__ == '__main__':
worker = Worker(name='xia', age=18, salary=10000)
worker.info()
worker.show()
print(worker.country)
worker.country = '美丽国' #重写了父类的属性
print(worker.country)
输出结果:
姓名xia 年龄18 薪水10000
我是worker的show
中国
美丽国
多继承:
#!/usr/bin/env python
# !coding:utf-8
# 顺序:继承遵循从左到右,从下到上的顺序(主要用于单继承,继承有父类,爷爷类,优先调用父类)
class Person(object):
'''定义一个人的类'''
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print("my name is {0} my age is {1}".format(self.name, self.age))
class Animal:
def __init__(self, sex):
self.sex = sex
def show(self):
print("这是动物类")
# 没有show()方法就去父类里去找,先找Person类,找到就停止,没找到继续找Animal类
class Worker(Person, Animal):
def __init__(self, name, age, salary, sex):
super().__init__(name, age)
Animal.__init__(self, sex)
self.salary = salary
def info(self):
print("姓名{0} 年龄{1} 薪水{2} 性别{3}".format(self.name, self.age, self.salary, self.sex))
# def show(self):
# print("我是worker的show")
if __name__ == '__main__':
worker = Worker(name='xia', age=18, salary=10000, sex='女')
worker.info()
worker.show()
输出结果:
姓名xia 年龄18 薪水10000 性别女
my name is xia my age is 18
深度优先和广度优先:
python2中多个类的继承算法叫深度优先,python3叫广度优先
class A:
def show(self):
print("A")
class B(A):
pass
class C(A):
def show(self):
print("C")
class D(B, C):
pass
if __name__ == '__main__':
d = D()
d.show()
# 深度优先执行顺序:先找D类,再找B类,再找A类,最后找C类
# 广度优先执行顺序:先找D类,再找B类,再找C类,最后找A类
深度优先执行顺序:
广度优先执行顺序:
类的多态:
class Animal:
def talk(self):
print("动物会叫")
class Cat(Animal):
def talk(self):
print("猫也会叫")
class Person(Animal):
def talk(self):
print("人也是会叫的")
def func(animal):
animal.talk()
if __name__ == '__main__':
# 对猫实例化
cat = Cat()
# 调用方式不需要修改就能拿到Cat类的信息
func(animal=cat)
func(animal=Person())
反射
简单的理解为:通过字符串的形式操作对象相关的属性。涉及到的方法有setattr,getattr,hasattr,delattr
class Person:
country = "中国"
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print('my name is {0},and my age is {1}'.format(self.name, self.age))
if __name__ == '__main__':
person = Person(name="xia", age=18)
print(hasattr(person, 'country')) # True
setattr(person, 'sex', '女') # 反射的新属性是字符串类型的
delattr(person, 'sex')
delattr(person, 'country') # 原属性是不允许被删除的
print(hasattr(person, 'sex'))
反射其他模块
使用__import__就可以导入其他模块的信息
day2 :
def login():
print('this is a login function')
def logout():
print('this is a logout function')
index = __import__('day2') # 导入day2模块,并赋值给字符串,字符串其实就是模块的对象
index.login()
import day2
f = getattr(day2, 'login')
f()
类案例实战
''使用面向对象的编程方式来写一个注册,登录,查看个人主页,退出的命令行系统'''
import json
import sys
class Auth:
def __init__(self):
pass
@property #特性方法
def input(self):
username = input('输入用户名\n')
pwd = input('输入密码\n')
return username, pwd #用到了返回值
# 从文件中获取用户名和密码
def login(self, username, pwd):
temp = json.load(open('login.json', 'r')) #反序列化读文件
lists = temp.split('|') #字符串的拆分变成列表
if lists[0] == username and lists[1] == pwd:
return True
else:
print("请登录")
@property
def register(self):
# 将用户名和密码写入到文件中
username, pwd = self.input
temp = username + '|' + pwd
json.dump(temp, open('login.json', 'w')) #序列化写文件
@property
def index(self):
temp = json.load(open('login.json', 'r'))
lists = temp.split('|')
print("欢迎{0}进入主页".format(lists[0]))
def exit(self):
sys.exit(1)
def main(self):
while True:
try:
p = input('1、登录 2、注册 3、查看主页 4、退出\n')
p = int(p)
if p == 1:
username, pwd = self.input
isLogin = self.login(username=username, pwd=pwd)
if isLogin:
self.index #不带()是特性方法引用时把方法当成属性
else:
self.register
elif p == 2:
self.register
elif p == 3:
self.index
elif p == 4:
self.exit()
except Exception as e:
continue
if __name__ == '__main__':
a = Auth() #类的实例化
a.main()
工厂设计模式
''结合工厂设计方法写一个上帝创造人的代码'''
根据不同的参数生成不同的对象,只需要知道工厂类和产品的父类,不需要关心产品的类型和创建过程
class Person:
def __str__(self):
return 'person'
def showPerson(self):
print("创造了一个人")
class Man(Person):
def __str__(self):
return 'man'
def show(self):
print("呵,男人")
class Women(Person):
def __str__(self):
return 'women'
def info(self):
print("呵,女人")
class Factory:
def creatPerson(self, obj):
if obj == 'man':
return Man()
if obj == 'women':
return Women()
if __name__ == '__main__':
factory = Factory()
# 根据不同的参数生成不同的对象,只需要知道工厂类和产品的父类
objMan = factory.creatPerson(obj='man')
objWomen = factory.creatPerson(obj='women')
objMan.show()
objWomen.info()