标签:出生日期 __init__ 技能 自定义对象 cme 就是 增加 减少代码冗余 erro
面向对象基础知识#1、 面向过程与面向对象
# 面向过程:
# 核心过程二字,过程即解解决问题的步骤,先干什么,再干什么
# 基于该思想写程序就好比在设计一条流水线,是一种机械式的思维方式
# 优点:复杂过程流程化,进而简单化
# 缺点:扩展性差
# 面向对象
# 核心是对象二字,对象是特征与技能的结合体
# 基于该思想编写程序就好比在创造一个世界,世界是由一个个对象组成的,是一种"上帝式"的思维方式
# 优点:可扩展性强
# 缺点:变成复杂度高,容易出现过度设计
# 2、类
# 对象是特征与技能的集合体,类是一系列对象相似的特征和技能的集合体
# 在现实世界中:一定是先有的一个个具体存在的对象,后总结出的类
# 在程序中:一定保证先定义类,后产生对象
#类体代码在类的定义阶段就会立刻执行
class Student:
school = ‘oldboy‘
def learn(self):
print(‘lenaring learing‘)
def choose_course(self):
print("choose course")
Student.learn(‘asdf‘)
# 调用类的过程又称为实例化
# 1、得到一个返回值,即对象,该对象是一个空对象stu1
# 2、Student.__init__(stu1,name,age,sex)
class Student:
school = ‘oldboy‘
def __init__(self,name,age,sex):
self.Name = name
self.Age = age
self.Sex = sex
def learn(self):
print(‘lenaring learing‘)
def choose_course(self):
print("choose course")
stu1 = Student(‘haha‘,18,‘male‘)
stu2 = Student(‘hehe‘,23,‘fmale‘)
print(stu1.__dict__)
print(stu1.school)
print(stu2.Name)
print(stu2.school)
# 在类定义的时候会生成一个类的名称空间,类的名称空间会包括类的数据属性名称和方法属性名称
# 在对象实例化后会生成对象的名称空间,会产生对象的数据属性名称,以及自定义对象的方法属性名称
# 对象的属性查找会现在对象自己的名称空间查找,如果没有会从类的名称空间查找,如果两者名称空间都有查找的属性,优先在对象的名称空间查找。
# 类里的方法是绑定给对象使用的,对象调用类的方法时,对自动将对象作为第一个参数传递给该方法。
class Teacher:
count=0
def __init__(self,name,course):
count = 0
self.Name = name
self.Course = course
Teacher.count+=1
def teach_course(self):
print("%s teaching course is %s" %(self.Name,self.Course))
th1 = Teacher(‘egon‘,‘python‘)
th2 = Teacher(‘oldboy‘,‘linux‘)
th1.teach_course()
print(th1.teach_course) #绑定方法
print(th1.count)
1.什么是继承?
是一种新建类的方式,新建类称为子类,子类会遗传父类的属性,可以减少代码冗余
在python中,子类(派生类)可以继承多个父类(基类,超类)
在python2中,类分为:金典类和新式类
新式类:继承了object类的类,以及该类的子类
金典类:没有继承object类的类,以及该类的子类
在python3中,统一都为新式类
‘‘‘
class OldboyPeople():
school="oldboy"
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def tell_info(self):
print("<名字:%s,年龄:%s,性别:%s>" %(self.name,self.age,self.age))
class OldboyStudent(OldboyPeople):
def learn(self):
print("%s is learning" %self.name)
def tell_info(self):
print("我是学生:",end=‘‘)
print("<名字:%s,年龄:%s,性别:%s>" %(self.name,self.age,self.age))
class OldboyTeacher(OldboyPeople):
def teach(self):
print("%s is teaching" %self.name)
stu1=OldboyStudent(‘huazai‘,12,‘male‘) #实例化一个对象
stu1.learn() #调用对象的方法
stu1.tell_info() #
teach1=OldboyTeacher(‘egon‘,‘18‘,‘male‘)
print(teach1.name) #调用对象自己名称空间的属性
teach1.teach() #调用类的名称空间的属性方法
teach1.tell_info() #调用父类名称空间的方法
#多继承
# 金典类:深度优先
# 新式类:广度优先
#在继承中,属性的查找顺序:对象自己-->类-->父类
#多继承
# 金典类:深度优先
# 新式类:广度优先
# 在python2中存在金典类和新式类,在python3中都是新式类
#
class A(object):
def test(self):
print(‘from A‘)
class B(A):
def test(self):
print(‘from B‘)
class C(A):
def test(self):
print(‘from C‘)
class D(B):
def test(self):
print(‘from D‘)
class E(C):
def test(self):
print(‘from E‘)
class F(D,E):
def test(self):
print(‘from F‘)
pass
f1=F()
f1.test()
print(F.__mro__)
#通过上述的例子,分别在python2和python3中测试,可以得出如下的继承顺序:
# 新式类:F-->D-->B-->E-->C-->A
# 金典类:F-->D-->B-->A-->E-->C
#继承的原理就是按照类的mro列表从左到右的顺序来的。
# 三条准则:
# 1.子类会先于父类被检查
# 2.多个父类会根据它们在列表中的顺序被检查
# 3.如果对下一个类存在两个合法的选择,选择第一个父类
super()
# 通过继承的方式查找
在python2中super(当前类名,self)
class Animal:
shool="oldboy"
class OldboyPeople(Animal):
# school="oldboy"
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def tell_info(self):
print("<名字:%s,年龄:%s,性别:%s>" %(self.name,self.age,self.age))
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level,salary):
# OldboyPeople.__init__(self,name,age,sex) #指定类 的方法调用,不存在严格意义上的继承关系
# super().__init__(name,age,sex) #通过super方法可以继承父类的相应的属性
super(OldboyTeacher,self).__init__(name,age,sex) # 在python2中要加上自己类名和self
self.level = level
self.salary = salary
def tell_info(self):
print("我是老师:",end="")
# print("<名字:%s,年龄:%s,性别:%s>" %(self.name,self.age,self.age))
# OldboyPeople.tell_info(self)
super().tell_info()
teach1=OldboyTeacher("egon",18,"male","10",‘1200‘)
teach1.tell_info()
print(teach1.shool)
print(OldboyTeacher.mro())
#继承的关系是:xx是xx 学生是人
#组合的关系是:xx有xx 学生有出生日期
class OldboyPeople():
school="oldboy"
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def tell_info(self):
print("<名字:%s,年龄:%s,性别:%s>" %(self.name,self.age,self.age))
class OldboyStudent(OldboyPeople):
def learn(self):
print("%s is learning" %self.name)
def tell_info(self):
print("我是学生:",end=‘‘)
print("<名字:%s,年龄:%s,性别:%s>" %(self.name,self.age,self.age))
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level,salary):
OldboyPeople.__init__(self,name,age,sex)
self.level = level
self.salary = salary
def teach(self):
print("%s is teaching" %self.name)
class Date:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
def tell_birth(self):
print("生日是《%s-%s-%s》" %(self.year,self.mon,self.day))
class course:
def __init__(self,name,price,per):
pass
stu1=OldboyStudent(‘huazai‘,20,‘male‘)
stu1.birth=Date(1992,10,5) #通过为对象添加属性,来实现组合的效果
stu1.birth.tell_birth() #对象可以通过属性方法调用组合类中的方法
1.多态
同一种事物的多种形态
2.多态性
在不考虑对象具体类型的情况下,直接使用对象(对象下的方法)
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod #使得继承该类的子类,必须定义与该方法名称相同的方法函数
def eat(self):
pass
@abc.abstractmethod
def run(self):
pass
class Pig(Animal):
def eat(self): #如果不定义eat 和run方法会报错
print("pig eating")
def run(self):
print("pig running")
class People(Animal):
def eat(self):
print("people eating")
def run(self):
print("people runnnig")
def eat(obj): #定义一个通用的方法 只要传入对象,就可以调用对象的方法,而不必关心是对象是什么
obj.eat()
obj1 = Pig()
obj2 = People()
eat(obj1) #
eat(obj2)
# pig1=Pig()
# peo1=People()
封装:
__开头的属性,只是在语法意义上的变形,并不能真的发生变形
这种变形之在类定义阶段发生一次,类定义之后在增加的__开头的属性不会变形
外部不能直接访问,内部可以直接访问
class Foo:
__N=1 #_Foo__N=1
def __f1(self):
print("Foo.f1")
print(Foo.__dict__)
print(Foo._Foo__N)
class Foo:
def f1(self):
print("Foo.f1")
self.__f2() #self._Foo__f2()
def __f2(self): #_Foo__f2()
print("Foo.f2")
class Bar(Foo):
def f2(self):
print("Bar.f2")
class Sub(Bar):
pass
s = Sub()
print(Sub.__mro__)
s.f1()
‘‘‘
封装:
数据:控制数据
方法:隔离复杂度
‘‘‘
class Student:
def __init__(self,name,age,sex):
# self.__name = name
# self.__age = age
# self.__sex = sex
self.set_info(name,age,sex)
def set_info(self,name,age,sex): #调用者想要修改属性,必须通过统一的借口调用才能实现
if type(name) is not str:
raise ("TypeError: name must be str")
if type(age) is not int:
raise ("TypeError: age must be int")
if type(sex) is not str:
raise ("TypeError: age must be str")
self.__name = name
self.__age = age
self.__sex = sex
def tell_info(self): #调用者想要调用属性 也必须通过统一的调用接口来查询
print("姓名:<%s>,年龄:<%s>,性别:<%s>" %(self.__name,self.__age,self.__sex))
stu1 = Student("huazai",18,‘male‘)
# stu1.__name = "hehe"
stu1.set_info("hehe",18,‘male‘)
stu1.tell_info()
‘‘‘
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
将函数属性转换成数据属性来访问
‘‘‘
# class People():
# def __init__(self,name,age,hight,weight):
# self.name = name
# self.age = age
# self.hight = hight
# self.weight = weight
#
# @property
# def bmi(self):
# return self.weight / (self.hight ** 2)
#
# p1 = People(‘huazai‘,12,1.8,80)
# p1.hight=1.75
# # print(p1.bmi())
# print(p1.bmi)
class People:
def __init__(self,name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self,obj):
self.__name = obj
@name.deleter
def name(self):
del self.__name
p1 = People("huazai")
# print(p1.name())
# print(p1.name)
p1.name = "Huazai"
print(p1.name)
# getattr()
# setattr()
# delattr()
# hasattr()
# 通过将字符串反射到对应的方法上
class FtpClient(object):
def __init__(self,host,port):
# self.conn = conn
self.host = host
self.port = port
self.conn = "conn"
def interactive(self):
while True:
cmd = input(">>").strip()
if not cmd:continue
cmd_l = cmd.split()
print(cmd_l)
if hasattr(self,cmd_l[0]): #判断方法是否存在
func = getattr(self,cmd_l[0]) #将字符串传换成方法
func(cmd_l)
def get(self,cmd_l):
print("getting... ")
def put(self):
print("putting...")
client = FtpClient(‘127.0.0.1‘,25)
client.interactive()
标签:出生日期 __init__ 技能 自定义对象 cme 就是 增加 减少代码冗余 erro
原文地址:http://blog.51cto.com/ronghuachen/2064613