houziaipangqi

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

写在前面:笔记全部是跟着老师一起敲的代码,最近电脑瓦特了,所以只能用老爷机的日记本记下老师上课讲的东西,但我运行不了

特别感谢的是xx学院的的刘老师,我都是边看他的课,边学他一起敲代码,然后晚上自己看,自己理解,感谢老师。

 

OOP-python面向对象
- python的面向对象
- 面向对象编程
-基础
-公有私有
-继承
-组合、Mixin
- 魔法函数
-魔法函数概述
-构造类魔法函数
-运算类魔法函数

1、面向对象概述(objectoriented,oo)
- OOP思想
-接触到任意一个任务,首先想到的是任务这个事件的构成,是由模型构成的
- 几个名词
-OO:面向对象
-OOA:面向对象的分析
-OOD:面向对象的设计
-OOI:XXX的实现
-OOP:XXX的编程
-OOA->OOD->OOI:面向对象的实现过程
- 类和对象的概念
-类:抽象名词,代表一个集合,共性的事务
-对象:具象的事务,单个个体
-如果说“学生”是一个类,那么“单个学生”就是对象
- 类具有两个内容
-表明事务的特征,叫做属性(变量)
-表明事务的功能或动作,称为成员方法(函数)

2、类的基本实现
- 类的命名
-遵守变量命名的规范
-大驼峰(由多个单词构成,每个单词首字母大写,单词跟单词相连)
-尽量避开跟python内置函数相似的命名
- 如何声明一个类
-必须用class关键字
-类由属性和方法构成,其他不允许出现
-成员属性定义可以直接使用变量赋值,如果没有值,可以使用None

-案例01.py
-实例化类
变量 = 类名() #实例化了一个对象
-访问对象成员
-使用点操作符
obj.成员属性名称
obj.成员方法
-可以通过默认内置变量检查类和对象的所有成员
-对象所有成员检查
#dict前后各有两个下划线
obj.__dict__

-类所有的成员检查
#dict前后各有两个下划线
class_name.__ict__

#定义一个空的类
class Student():
#一个空类,pass代表直接跳过,此处必须有pass
pass
#定义一个对象
siqi = Student():

#再定义一个类,用来描述听python的学生
class PythonSstudent():
#用None给不确定的元素赋值
name = None
age = 18
course = "Python"
#注意 def doHomework的缩进层级
#注意 系统默认有一个self参数
def doHomework(self):
print("我在做作业")
#推荐在函数末尾使用return语句
return None
#实例化一个叫siqi的学生,是一个具体的人
siqi = PythonStudent()
print(siqi.name)
print(siqi.age)
#注意 成员函数的调用没有传递参数
siqi.Homework()
在下面设置好的OOP虚拟环境下运行代码,需要进行以下步骤
-1、python控制界面 File
-2、project interpreter
-3、往右看,点击小齿轮,添加add local
-4、左边选择anaconda
-5、右边点击existing environment,找到anaconda安装目录下的envs文件夹,点击里面刚创建好的OOP,里面点击bin文件夹。点击里面的python或者python3或者python3.6都可以,点击确定
运行时,右击debug

3、anaconda虚拟环境创建(linux环境与windows略有不同)
-anaconda主要是一个虚拟环境管理器
-conda list:显示anaconda安装的包
-conda env list:显示anaconda的虚拟环境列表
-conda creat -n OOP python=3.6:创建python版本为3.6的虚拟环境,名称为OOP

 

4、类和对象的成员分析
- 类和对象都可以储存成员,成员可以归类所有,也可以归对象所有
- 对象在访问成员时,只是访问其内容,不会重新储存一分新的成员在其自己的空间。
- 对象访问一个成员时,如果对象中没有该成员,尝试访问类中的同名成员,如果对象中有此成员,一定使用对象中的成员
- 创建对象的时候,类中的成员不会放入对象中,而是得到一个空对象,没有成员
- 通过对象对类中成员重新赋值或者添加成员时,只会保存在对象中,不会修改类成员

class A():
name = "siqi"
age = 18
def say(self):
self.name = "aaaa"
self.age = 200
#此时,A成为类实例    
print(A.name)
print(A.age)
print(id(A.name))
print(id(A.age))

a = A()
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
此时上下两个id是一样的,指向同一片内存

 

5、关于self
- self 在对象的方法中表示当前对象本身,如果通过对象调用一个方法,那么该对象会自动传入到当前方法的第一个参数中
- self并不是关键字,只是一个用于接受对象的普通参数,理论上可以用任何一个普通变量名代替
- 方法中有self形参的方法称为非绑定类的方法,可以通过对象访问,没有self的称为绑定类的方法,只能通过类访问
- 使用类访问绑定类的方法时,如果类方法中国需要访问当前类的成员,可以通过__class__成员名来访问

class A():
    name = "siqi"
    age = 18
    def say(self):
        self.name = "aaaa"
        self.age = 200
        print("my name is {0}".format(self.name))
        print("my age is {0}".format(self.age))
siqi = A()
siqi.say()
        

class Teacher():
    name = "siqi"
    age = 18
    def say(self):
        self.name = "houzi"
        self.age = 19
        print("my name is {0}".format(self.name))
        print("my age is {0}".format(self.age))
    def sayagain():
        #调用类成员变量需要用__class__
        print(__class__.name)
        print(__class__.age)
        print("i love pangqi")
t = Teacher()
t.say()
#调用绑定类参数必须使用类名
Teacher.sayagain()

 

#关于self的案例

class A():
name = "siqi"
age = 18
def _init_(self):
self.name = "aaa"
self.age = 200
def say(self):
print(self.name)
print(self.age)
class B():
name = "bbb"
age = 100

a = A()
a.say()
A.say()#报错
A.say(a)#此时,self被a替换
A.say(A)#此时,把A作为参数传入

A.say(B)#此时,传入额是实例B,因为B具有name和age属性,所以不会报错
以上代码,利用了鸭子模型(有翅膀,会呱呱叫,会游泳,就判定为是鸭子)

 

6、面向对象的三大特性
-封装
-继承
-多态

-6.1 封装
- 封装就是对对象的成员进行访问限制
-封装的三个级别:
- 公开,public
- 受保护的,protected
- 私有的,private
-public、private、protected不是关键字
- 判别对象的位置
- 对象内部
- 对象外部
- 子类中
- 私有的
- 私有成员时最高级别的封装,只能在当前类或对象中访问
- 在成员前面添加两个下划线就行
- python的私有并非真正的私有,是一种改名策略,是一种name mangling技术,可以使用对象._classname_attributename进行访问

#私有变量案例

class Person():
#name 是共有成员
name = "siqi"
#age是私有成员
__age = 18
p = Person():
#name是公有变量
print(p.name)
#age是私有的
print(p.__age)#报错    
print(p._Person_age)不会报错,但不要使用

 

- 受保护的封装 protected

-受保护的封装是将对象成员进行一定级别的封装,然后,在类中或子类中可以进行访问,但是在外部不可以
-封装方法:在成员名称前添加一个下划线即刻
- 公开的,公用的 public
-公共的封装实际对成员没有任何操作,任何地方都可以访问

# 继承
- 继承就是一个类可以获得另一个类中的成员属性和方法
- 作用:减少代码,避免重复工作,增加代码的复用功能,同时可以设置类与类直接的关系
- 继承与被继承的概念:
-被继承的类叫父类,也叫基类
-继承的类叫,自类,也叫派生类
- 继承与被继承一定存在一个 is-a 的关系
语法例:

class Person():
name = "NoName"
age = 0
def sleep(self):
print("sleeping...")
#父类写在括号里    
class Teacher(Person):    
pass

t = Teacher()
print(t.name)
print(Teacher.name)

 

 

- 继承的特征
-所有的类都继承自object类,即所有的类都是object类的子类
-子类一旦继承父类,则可以使用父类中除私有成员以外的所有内容
-子类继承父类后并没有将父类成员完全复制到子类中,而是通过引用关系访问
-子类中可以定义独有的成员属性和方法
-子类中定义的成员和父类成员如果相同,则优先使用子类成员
-子类如果想扩充父类的方法,可以在定义新方法的同时访问父类成员来进行代码重用,可以使用 父类名.父类成员 的格式来调用父类恒源,也可以使用super().父类成员的格式来调用

class Person():
name = "NoName"
age = 0
__score = 0 #考试成绩是秘密,只能自己知道
_petname = "qiqi" #小名,是保护的,子类可以用,但不能公用
def sleep(self):
print("sleeping...")
def work(self):
print("make some money")

#父类写在括号里    
class Teacher(Person):
name = "houzi" #子类和父类相同名称的成员
teacher_id = "9527"#子类中新定义的成员
def make_test(self)#子类中新定义的恒源
print("attention")
def work(self):
#扩充父类的work功能,只需要调用父类相应的函数
Person.work(self) #方法一
self.make_test()
super().work()#方法二
self.make_test()

t = Teacher()
print(t.name)
print(t._petname)
print(t.work)
#公开访问私有变量,报错
print(t.__score)#报错,不可访问

 

# 继承变量函数的查找顺序问题
-优先查找自己的变量
-没有则查找父类
-构造甘薯如果本类中没有定义,则自动查找调用父类构造甘薯#一会儿讲
-如果本类没有定义,则不能继续向上查找

- 构造函数
-是一类特殊的函数,在类进行实例化之前呢进行调用
-如果定了构造函数,则实例化时使用构造函数,不查找父类构造函数
-如果子类没有定义,则自动查找父类的构造函数
-父类的构造函数带参数,则构造对象的参数应该按父类参数构造


例:

#构造函数概念
class Dog():
#__init__就说构造函数
#每次实例化的时候,第一个被自动调用
def __init__(self):
print("88755")
kk = Dog()


#继承中的构造函数-1
class Animal():
pass
class BuAnimal(Animal):
pass
class Dog(BuAnimal):
#__init__就说构造函数
#每次实例化的时候,第一个被自动调用
def __init__(self):
print("88755")
#实例化的时候,自动调用了Dog的构造函数    
kk = Dog()


#继承中的构造函数-2
class Animal():
pass
class BuAnimal(Animal):
def __init__(self):
print("pgdog")
class Dog(BuAnimal):
#__init__就说构造函数
#每次实例化的时候,第一个被自动调用
def __init__(self):
print("88755")
#实例化的时候,自动调用了Dog的构造函数
#因为找到了构造函数,则不会再查父类的构造函数    
kk = Dog()

#cat没有写构造函数
class Cat(BuAnimal):
pass
#此时应该自动调用构造函数,因为cat没有构造函数,所以查找父类的构造函数,在BuAnimal时停止    
c = Cat()


#继承中的构造函数-3
class Animal():
pass
class BuAnimal(Animal):
def __init__(self,name):
print("pgdog i {o}".format(name))
class Dog(BuAnimal):
#__init__就说构造函数
#每次实例化的时候,第一个被自动调用
def __init__(self):
print("88755")
#实例化的时候,自动调用了Dog的构造函数
#因为找到了构造函数,则不会再查父类的构造函数    
kk = Dog()

class Cat(BuAnimal):
pass
#!!此时报错,因为父类的构造函数需要两个参数,而此时只给了一个    
c = Cat()


- super
-super不是一个关键字,是一个类
-super的作用是获取MRO(method resolution order)列表中的第一个类
-super与父类没有任何直接关系,但通过super可以调用父类
-super:使用两个方法,参见在构造函数中调用父类的构造函数 

例:
print(type(super))
help(super)

 

 

 

 

 

posted on 2018-08-13 23:28  houziaipangqi  阅读(250)  评论(0编辑  收藏  举报