面向对象

1.初识类:

# 定义一个函数,我们使用关键字 def
"""
def 函数名(参数):
'''函数说明'''
函数体
return 返回值
""" def func():
print("func execute...")
# 定义一个类 使用关键字 class
"""
class 类名:
'''类说明'''
类体
""" class C:
pass
class Person:
role = 'person' # 属性 def walk(self):
print("person is walking ... ") # 动态属性

2.类属性引用和实例化

属性引用:类型.属性

class Person:
role = 'person' def walk(self):
print("person is walking...") print(Person.role) # 查看人的role属性
print(Person.walk) # 引用人的走路方法,注意,这里不是在调用,引用的是函数地址

实例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

class Person:
role = 'person' def __init__(self, name):
self.name = name def walk(self):
print("person is walking...") # 类实例化-->对象 对象 = 类名(参数) p1 = Person("zhangsan") # Person("zhangsan") 调用__init__(self, name)方法,构造方法 # 查看对象的属性 调用对象的方法
print(p1.role)
p1.walk()

3.类命名空间与对象、实例的命名空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:静态属性和动态属性

静态属性就是直接在类中定义的变量        类的数据属性是共享给所有对象的
动态属性就是定义在类中的方法 类的动态属性是绑定到所有对象的 创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性 在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常

4.面向对象三大特性

继承:

新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

python中类的继承分为:单继承和多继承

class ParentClass1:  # 定义父类
pass class ParentClass2: # 定义父类
pass class SubClass1(ParentClass1): # 单继承,基类是ParentClass1,派生类是SubClass
pass class SubClass2(ParentClass1, ParentClass2): # python支持多继承,用逗号分隔开多个继承的类
pass

先抽象在继承:

增强代码重用性

子类可以自己实现新的属性和方法,或者重新定义父类的,不会影响父类。

在python3中,子类执行父类的方法也可以直接用super方法.

抽象类与接口类

继承有两种用途:

一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)  

二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

接口定义:

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass class Wechatpay(Payment):
def pay(self, money):
print("Wechatpay pay...") def fuqian(self, money):
print('微信支付了%s元' % money) p = Wechatpay()
p.pay(100)
依赖倒置原则:
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程

抽象类:
只能被继承,不能实例化

# 一切皆文件
import abc # 利用abc模块实现抽象类 class All_file(metaclass=abc.ABCMeta):
all_type = 'file' @abc.abstractmethod # 定义抽象方法,无需实现功能
def read(self):
'子类必须定义读功能'
pass @abc.abstractmethod # 定义抽象方法,无需实现功能
def write(self):
'子类必须定义写功能'
pass # class Txt(All_file):
# pass
#
# t1=Txt() #报错,子类没有定义抽象方法 class Txt(All_file): # 子类继承抽象类,但是必须定义read和write方法
def read(self):
print('文本数据的读取方法') def write(self):
print('文本数据的读取方法') class Sata(All_file): # 子类继承抽象类,但是必须定义read和write方法
def read(self):
print('硬盘数据的读取方法') def write(self):
print('硬盘数据的读取方法') class Process(All_file): # 子类继承抽象类,但是必须定义read和write方法
def read(self):
print('进程数据的读取方法') def write(self):
print('进程数据的读取方法') wenbenwenjian = Txt() yingpanwenjian = Sata() jinchengwenjian = Process() # 这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read() print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

抽象类与接口类:

抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计 

多继承接口,接口定义一种规范

多态:多态指的是一类事物有多种形态

import abc

class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def talk(self):
pass class Person(Animal):
def talk(self):
print("person .. ") class Dog(Animal):
def talk(self):
print("Dog .. ") def talk(obj):
obj.talk() talk(Person())

封装:

隐藏对象的属性和实现细节,仅对外提供公共访问方式

【封装原则】

      1. 将不需要对外提供的内容都隐藏起来;

      2. 把属性都隐藏,提供公共方法对其访问。

私有变量和私有方法:使用双下划线

# 其实这仅仅这是一种变形操作
# 类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式: class A:
__N = 0 # 类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N def __init__(self):
self.__X = 10 # 变形为self._A__X def __foo(self): # 变形为_A__foo
print('from A') def bar(self):
self.__foo() # 只有在类内部才可以通过__foo的形式访问到. # A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
这种自动变形的特点:

1.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。

2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。

3.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
class A:
__N = 0 # 类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N def __init__(self):
self.__X = 10 # 变形为self._A__X def __foo(self): # 变形为_A__foo
print('from A') def bar(self):
self.__foo() # 只有在类内部才可以通过__foo的形式访问到. # A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
a = A()
# a.bar() print(a._A__N) # 知道类名,属性名 就可以访问
print(a._A__foo())

私有方法:在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

5.property属性:

一个静态属性property本质就是实现了get,set,delete三种方法

class Goods:

    def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8 @property
def price(self):
# 实际价格 = 原价 * 折扣
new_price = self.original_price * self.discount
return new_price @price.setter
def price(self, value):
self.original_price = value @price.deleter
def price(self):
del self.original_price obj = Goods()
obj.price # 获取商品价格
obj.price = 200 # 修改商品原价
print(obj.price)
del obj.price # 删除商品原价

classmethod:

class Classmethod_Demo():
role = 'dog' @classmethod
def func(cls):
print(cls.role) Classmethod_Demo.func()

staticmethod:

class Staticmethod_Demo():
role = 'dog' @staticmethod
def func():
print("当普通方法用") Staticmethod_Demo.func()

6.isinstance和issubclass

class A(object):
pass a = A() # isinstance(obj,cls)检查是否obj是否是类 cls 的对象
print(isinstance(a, object))
# issubclass(sub, super)检查sub类是否是 super 类的派生类
print(issubclass(A, (object)))

7.反射

通过字符串的形式操作对象相关的属性 -- 自省

hasattr  是否有该属性
getattr 获取属性
setattr 设置属性
delattr 删除属性
class Person():
role = 'person' def __init__(self, name):
self.name = name def walk(self):
print("person is walking ...") p = Person("zhangsan")
print(hasattr(p, 'name')) print(getattr(p, 'role')) print(setattr(p, 'name', 'lisi'))
print(getattr(p, 'name')) print(delattr(p, 'role'))
print(getattr(p, 'role')) # AttributeError

__str__和__repr__

format_dict={
'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type def __repr__(self):
return 'School(%s,%s)' %(self.name,self.addr)
def __str__(self):
return '(%s,%s)' %(self.name,self.addr) def __format__(self, format_spec):
# if format_spec
if not format_spec or format_spec not in format_dict:
format_spec='nat'
fmt=format_dict[format_spec]
return fmt.format(obj=self) s1=School('oldboy1','北京','私立') print('from repr: ',repr(s1))
print('from str: ',str(s1))
print(s1) '''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))

python基础篇_006_面向对象的更多相关文章

  1. python基础篇(四)

    PYTHON基础篇(四) 内置函数 A:基础数据相关(38) B:作用域相关(2) C:迭代器,生成器相关(3) D:反射相关(4) E:面向对象相关(9) F:其他(12) 匿名函数 A:匿名函数基 ...

  2. 面试题之第一部分(Python基础篇) 80题

    第一部分(python基础篇)80题 为什么学习Python?==*== # 1. python应用于很多领域,比如后端,前端,爬虫,机器学习(人工智能)等方面,几乎能涵盖各个开发语言的领域,同时它相 ...

  3. Python基础篇(一)_基本语法元素

    Python基础篇——基本语法元素 缩进:体现强制可读性,一般缩进4个空格.一个或多个Tab 注释:单行注释----以 # 开头 多行注释----每行以 # 开头,以 # 结束 变量:无须提前声明.可 ...

  4. python基础篇-day1

    python基础篇 python是由C语言写的: pass 占位符: del,python中全局的功能,删除内存中的数据: 变量赋值的方法: user,pass = 'freddy','freddy1 ...

  5. python基础篇之进阶

    python基础篇之进阶 参考博客:http://www.cnblogs.com/wupeiqi/articles/5115190.html python种类 1. cpython  使用c解释器生产 ...

  6. python基础篇(六)

    PYTHON基础篇(六) 正则模块re A:正则表达式和re模块案例 B:re模块的内置方法 时间模块time A:时间模块的三种表示方式 B:时间模块的相互转换 随机数模块random A:随机数模 ...

  7. python基础篇(五)

    PYTHON基础篇(五) 算法初识 什么是算法 二分查找算法 ♣一:算法初识 A:什么是算法 根据人们长时间接触以来,发现计算机在计算某些一些简单的数据的时候会表现的比较笨拙,而这些数据的计算会消耗大 ...

  8. python基础篇(一)

    PYTHON基础篇(一) 变量 赋值 输入,输出和导入 A:输入 B:输出 C:导入 运算符 A:算数运算符 B:比较运算符 C:赋值运算符 D:位运算符 E:逻辑运算符 F:成员运算符 G:身份运算 ...

  9. python基础篇(二)

    PYTHON基础篇(二) if:else,缩进 A:if的基础格式和缩进 B:循环判断 C:range()函数和len()函数 D:break,contiue和pass语句 for,while循环 函 ...

随机推荐

  1. ☆ [NOI2014] 魔法森林 「LCT动态维护最小生成树」

    题目类型:\(LCT\)动态维护最小生成树 传送门:>Here< 题意:带权无向图,每条边有权值\(a[i],b[i]\).要求一条从\(1\)到\(N\)的路径,使得这条路径上的\(Ma ...

  2. [JSOI2008]Blue Mary开公司[李超线段树]

    题面 bzoj luogu 好久以前听lxl讲过 咕掉了.. 竟然又遇到了 安利blog #include <cmath> #include <cstring> #includ ...

  3. cogs2479 偏序(CDQ套CDQ)

    题目链接 思路 四维偏序 \(CDQ\)套\(CDQ\),第一维默认有序.第二维用第一个\(CDQ\)变成有序的.并且对每个点标记上第一维属于左边还是右边.第二个\(CDQ\)处理第三维,注意两个\( ...

  4. Java基础 -- final关键字

    在java的关键字中,static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.下面我们来了解一下final ...

  5. GroupBox、TextBox、CheckBox、ToolStrip、RichTextBox、Timer控件

    GroupBox:划分窗体区域,内部可以拖放组件 TextBox:可编辑文本框,也可设置为只读 属性:ReadOnly(只读).PasswordChar(密码显示的符号,如*).Multiline(多 ...

  6. linux,pthread(转)

    互斥量.条件变量与pthread_cond_wait()函数的使用,详解(二)   1.Linux“线程” 进程与线程之间是有区别的,不过linux内核只提供了轻量进程的支持,未实现线程模型.Linu ...

  7. DirectX11--深入理解HLSL常量缓冲区打包规则

    HLSL常量缓冲区打包规则 DirectX11 With Windows SDK完整目录 欢迎加入QQ群: 727623616 可以一起探讨DX11,以及有什么问题也可以在这里汇报. 尽管打包规则并不 ...

  8. JavaScript对象 Object类型基础

    前言 JavaScript 对象是整个语言学习的一个难点.本文主要带大家入门学习Object知识 对象定义 javascript的基本数据类型包括undefined.null.boolean.stri ...

  9. 「WC2018」通道

    没有代码能力... LOJ #2339 Luogu P4220 UOJ #347 题意 给定三棵树$ T1,T2,T3$,求一个点对$ (x,y)$使得$ T1.dist(x,y)+T2.dist(x ...

  10. XSS闯关游戏准备阶段及XSS构造方法

    请下载好XSS闯关文件后,解压后放在服务器的对应文件夹即可 在该闯关中,会在网页提示一个payload数值 payload,翻译过来是有效载荷 通常在传输数据时,为了使数据传输更可靠,要把原始数据分批 ...