python面向对象OOP

一切皆对象

OOP的核心思想

类: 从近似的对象中抽象出类
对象: 然后再从类出实例化出对象

OPP三大特性

封装
封装就是将抽象的数据(变量)和行为(函数)打包,形成一个逻辑上的整体(即类);
封装可以增强安全性(数据)并简化编程(函数),用户只能通过类对外接口的访问权限来使用类的成员。
继承
一个类可以以 class newclsname():来开始全新构造(实际上会默认继承自object);
也可以从某个已经存在的类继承。继承的类叫做subclass。比如要构造蜘蛛这个类,可以从昆虫这个类继承。构建学生,雇员,战士都可以从人这个类继承。
多态
因为类具有继承关系,子类可以向上转型被看做是父类的类型,比如无论是战士还是快递员,都是人类。也因为有了继承关系,子类可以继承父类的所有方法和属性,当然也可以重载父类的成员函数及属性。例如,当子类(直升机)和父类(飞机)都存在相同的fly()方法时,子类的fly()覆盖了父类的fly(),在运行时就总是会调用子类的fly()。这就是继承带来的多态。

关于类与对象操作的BIFs

type() 返回对象类型
id(), 查看对象id
dir(), 查看对象下变量及函数
issubclass(),isinstance(), super(),类,实例,调父类
hasattr(),getattr(),setattr(),delattr()类属性操作
globals(),locals(), 全局与局部的名称空间
import(),reload(), 模块的导入与重载

class B:
    a = 2
    pass
class A(B): #A 继承 B
    a = 1
    __d = 2 #__d被隐藏
    def __init__(self):
        self.b = 2
        self.__c = 3
    def func1(self):
        print(super().a) # 访问父类的属性
    '''
    定义静态方法,跟普通函数没什么区别,与类和实例都没有所谓的绑定关系,它只不过是碰巧存
    在类中的一个函数而已。不论是通过类还是实例都可以引用该方法。
    静态方法的使用场景:
    如果在方法中不需要(也不能)访问任何实例方法和属性,纯粹地通过传入参数并返回数据的功能性方法,
    那么它就适合用静态方法来定义,它节省了实例化对象的开销成本,往往这种方法放在类外面
    的模块层作为一个函数存在也是没问题的,而放在类中,仅为这个类服务。
    '''
    @staticmethod 
    def func2():
        pass
    @classmethod # 类方法
    def func3(cls):
        pass
class C:
    pass
a = A()
type(a) #__main__.A
id(a) #地址
dir(a) # [...'a', 'b', 'func1', 'func2', 'func3']
dir(A) # [...'a', 'func1', 'func2', 'func3']
issubclass(A, B) # true
isinstance(a,C) # False
a.func1() # 2
hasattr(A, 'func3') # True
getattr(A, 'a') # True # getattr(A, '__d')报错
setattr(A, 'a', 100) # 设置类属性a的值为100, 会影响所有其类的对象的属性a的值
setattr(a, 'a', 200) # 设置对象a的属性a的值为200, 不会影响类属性a的值
a.a # 200
A.a # 100
delattr(a, 'a') #删除对象a的属性a,不影响类的属性a
a.a #100
delattr(A, 'a') #删除类A的属性a, 但是还有个从父类继承过来的属性a
a.a # 2
delattr(B, 'a') #把类B的属性a也删除
a.a #报错 'A' object has no attribute 'a'
globals()
locals()

类的创建和实例化

创建类
 class关键字
 指定继承
 定义类的成员:属性(类变量,实例变量),方法(类方法,实例方法)
实例化类

#完成一个学生类的设计
#要求能查看总学生人数,全部学生姓名,毕业分数标准1000,已经毕业学生数量。
#实现考试方法,成绩分数如果大于60分代表其通过考试,分数计入该学生总分。
#如果该学生累计分数达到1000分,该学生即毕业
#实现查分方法,向该学生返回是否已经毕业,或者还差多少分数才能毕业
#实现查询所有已毕业学生数量的功能
#实现查询所有学生数量的功能
#实现查询所有学生姓名的功能
class Student():
    student_total = 0
    student_list = []
    student_graduated = 0
    pass_score = 1000
    
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender
        self.__score = 0
        Student.student_total += 1
        Student.student_list.append(name)
    def exam(self, score):
        if score < 60 :
            return 'Sorry, failed!'
        else:
            self.__score += score
            return 'Good, your score is updated to '+str(self.__score)+' now!'
        if self.__score >= Student.pass_score :
            Student.student_graduated += 1
    def check(self):
        if self.score < Student.pass_score:
            return Student.pass_score - elf.score, ' scores left to achieve!'
        else:
            return 'You have graduated!'
    @classmethod
    def get_student_list(cls):
        return Student.student_list
    @classmethod
    def get_student_graduate(cls):
        return Student.student_graduated

类的内部结构

数据成员: [用于处理类及实例对象的相关数据]
 类变量: 在类中且在函数体外,实例之间共享
 实例变量: 定义在方法中, 作用于当前实例的类
方法成员(在类中定义的函数叫方法) :
 类方法:定义时需要使用@classmethod装饰器, 第一个参数为cls
 实例方法:绑定到实例的方法, 第一个参数为self,
 静态方法[普通方法]:1)定义的时候使用@staticmethod装饰器。2)静态方法没有参数限制, 不需要实例参数self和类参数cls 3)静态法可以通过类名访问, 也可以通过实例访问。

# 实例方法:
# 是指该类的每个实例都可以调用到的方法。只有实例能调用实例方法。定义时第一个形参为self

# 类方法:
# 类方法是将类本身作为对象进行操作的方法。类对象和实例都可以调用类方法。
#定义时以@classmethod进行装饰,其第一个参数是类,约定写为cls。
# 实例方法和类方法都是依赖于python的修饰器来实现。 
#对象方法以self参数,类方法以cls参数来传递。

# cls
# cls是指向类的指针,在类方法中第一个形参要命名为cls.

# self
# self是指向每个独立对象的指针.在实例方法中第一个形参被命名为self,以区别其它函数。 

既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们有什么区别呢
从它们的使用上来看,
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

类的继承与多态

继承
 创建一个类时可以从新开始, 也可以从已经有的类继承下来
 super()子调用父类的方法
多态
 因为类具有继承关系, 子类可以向上转型被看做是父类的类型, 比如
无论是战士还是快递员, 都是人类。
 有了继承关系, 子类可以继承父类的所有方法和属性, 当然也可以
父类的成员函数及属性。
 例如, 当子类(直升机) 和父类(飞机) 都存在相同的fly()方法时, 子
类的fly()覆盖了父类的fly(), 在运行时就总是会调用子类的fly()。
 这就是继承带来的多态

# 多态的概念是应用于Java和C#这一类强类型语言中,
# Python是弱类型语言,Python崇尚“鸭子类型”
# 在Python世界中,一切都是对象

class A:
    def bar(self):
        print ('A.bar')
class B(A):#继承自A
    def car(self):
        print ('B.car')

#和A,B类型不相关的类C
class C():
    def sar(self):
        print ('C.sar')
    def car(self):
        print('C.car')

def fun1(obj):#接收一个参数obj
    obj.car()#调用该参数下的car()方法。而不关心obj到底是什么类型~

b1=B()
c1=C()

fun1(b1)#一切皆对象,不care是什么class
fun1(c1) #一切皆对象,不care是什么class

访问控制

Python没有像其它语言有访问控制的关键字, 例如private、 protected等等。 Python通过命名约定来实
现的访问控制
 对模块级的控制, 通过在标识符前加单下划线 _ 实现。
 对类内部的属性及方法, 通过在在标识符前加双下划线 __ 来实现的私有化
 类中两个双下划线包裹的属性或方法为特殊方法 __func__

Magic Method

魔法方法就是可以给你的类增加魔力的特殊方法, 如果你的对象实现(重载) 了这些方法中的某一个, 那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为, 这些会自动发生。它们经常是两个下划线包围来命名的。(后续补)

python 中 __name__ == ‘__main__’ 的作用

有句话经典的概括了这段代码的意义:
“Make a script both importable and executable”
意思就是说让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可执行。

如果我们是直接执行某个.py文件的时候,该文件中那么” __name__ == ‘__main__’ “是True,但是我们如果从另外一个.py文件通过import导入该文件的时候,这时__name__的值就是我们这个py文件的名字而不是__main__。

这个功能还有一个用处:调试代码的时候,在”if name == ‘main’“中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!

模块与包

模块module定义:一个.py文件,包含了对象定义与语句
 模块作用:用来从逻辑上组织代码
 模块使用:
搜索路径(标准模块, 自定义与第三方模块)路径
搜索路径设置(修改sys.path(sys.path.append()), 设置环境变量)
导入方法
import test#作为模块空间导入
from module_name import class_name #指定模块下具体的类, 对象导入,并入当前空间
from module_name import * #将模块下所有对象导入, 并入当前空间

包package定义:
含有__init__.py的文件夹被称为包, __init__.py文件用于标识当前文件夹是一个包.(该文件可以为空,但必须有),包用于组织模块, 通常把功能相近的模块进行再次封装成为包。
 包的目录结构:模块,子包,子包下的子包
 包的安装, 导入与访问
包的安装(pip,conda)
不同的导入方式(假设包名为test):
import test#导入__init__.py这个moduel。
from test import * #导入__init__.py这个moduel下所有对象导入到当前空间。
from test.test_level1.test_level2 import test_level2 #导入的层次目录下的模块。还是模块

import sys
sys.path
sys.path.append('d:/')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值