在面向对象的语言中,除了方法、对象,剩下的一大重点就是类了,从意义上来讲,类就是对具有相同行为对象的归纳。当一个或多个对象有相同属性、方法等共同特征的时候,我们就可以把它归纳到同一个类当中。在使用上来讲,类的存在,就是为了方便管理对象。python中定义一个类的代码如下:

class Simple_class(object):
#定义一个名为Simple_class的类,python3以后默认object做为类的基类,这里不讨论新式和旧式类的区别
height = 1.58#定义一个类变量
def __init__(self,name,age,):#重写类的初始化,
#使其在初始化的时候需要传入name,age两个参数。self为类方法的默认参数
self.name = name #定义两个对象变量
self.age = age
def Print_details(self):#定义一个名为Print_details的对象方法
print("Print_details方法调用:name is %s,age is %d"%(self.name,self.age))
print("未初始化访问类变量:height = ",Simple_class.height)# 访问类变量
try:
print(Simple_class.name) #访问实例变量 因为会报错,为了程序代码执行 给了一个异常处理
except AttributeError as error:
print("未初始化之前访问实例变量的异常信息:",error)
obj = Simple_class("object",115) #生成一个类的实例对象
obj.height = 1.88
print("初始化之后赋值给实例的类变量 height = ",obj.height)
print("初始化之后的原始类变量:height = ",Simple_class.height)
print("初始化之后访问实例变量:name is ",obj.name)#访问实例变量
obj.Print_details()#调用对象方法
# /////输出结果如下 ///////
/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/penglong/Documents/python/s10/day4/blog.py
未初始化访问类变量:height = 1.58
未初始化之前访问实例变量的异常信息: type object 'Simple_class' has no attribute 'name'
初始化之后赋值给实例的类变量 height = 1.88
初始化之后的原始类变量:height = 1.58
初始化之后访问实例变量:name is object
Print_details方法调用:name is object,age is 115

  

  以上,我们定义了一个类,类中包括一个重写的初始化方法,一个普通类方法。一个类变量,两个实例变量。从输出内容上我们来分析一下类变量和实例变量的区别,在实例化对象之前,是可以直接访问类变量并且取出赋值给别的变量,而实例变量则是在实例化之后,只能通过实例对象访问的变量,如果在有具体的实例对象之前直接通过类去访问,则程序会报错。这是二者的区别。从使用意义上来讲,个人认为,类变量更像是实例的默认变量,他是每一个实例对象带有的默认变量且有值,这个值在实例化对象之后可以进行修改,不影响其他实例对象。而实例变量则是各个实例的特有变量,必须要进行赋值之后才能使用。再说初始化方法和我们定义的方法,初始化方法属于类方法,可以直接调用。而对象方法需要通过实例调用。

在上一段代码中有一个关于基类的概念,实际上也就是继承。在编写代码的时候,我们想对一个类进行一些额外的扩充,而又不影响它本身的状态,那就可以写一个子类来满足,这里先从单重继承说起,代码如下:

class father_class(object):
#定义一个名为father_class的类,他既是子类的父类,又是子类的子类的基类
name = "父类" #定义一个类变量
def log(self):
#定义一个log方法 输出类名,这里不用self.__class取,是为了在子类调用时self会指向子类自身,不方便日志分辨。
print("father_class")
def public_func(self):#定义一个public_func方法,输出此方法是否被子类修改过
print("未修改")
class son_class(father_class): #定义一个子类,直接继承父类
son_name = "子类"#定义一个类变量
def son_log(self): #定义自身的log
print("son_class")
def public_func(self):#修改父类提供的公共方法
print("子类修改父类方法")
class grandson_class(son_class):
#定义一个名为grandson_class的类继承自son_class由于son_calss也是别人的子类
#所以son_class的父类是本类的基类
grandson_name = "子类的子类"
def grandson_log(self):#定义自身log
print("grandson_class")
def public_func(self):#对基类方法进行修改
print("子类修改基类方法")
########父类的实例对象##########
father = father_class() #生成一个父类的实例对象
name = father.name
#获取类变量的值并打印,类变量本身不用实例化也可以获取,但下文需要实例调用方法,所以就先生成了
print("父类访问自身类变量:",name)
father.log()#父类调用自身的方法
father.public_func()
#######子类的实例对象###########
son = son_class()#实例化一个子类对象
name = son.name #子类去获取父类的类变量并这打印。输出结果无误,说明子类可以继承父类所有的类变量。
#同理也可以继承父类所有实例变量,代码未举例,但原理一样
print("子类访问父类变量:",name)
son.log()#子类调用父类的方法,输出结果无误,说明子类可以继承父类所有的方法
name = son.son_name#子类访问自身类变量的值并打印,结果无误,说明子类可以增加类变量
print("子类访问自己的类变量:",name)#
son.son_log()#子类调用自己的log方法,说明子类可以扩充自己的方法
son.public_func()#子类调用父类的方法,但输出结果不同 ,因为我们在子类中进行过修改,说明子类可以修改父类方法
#########子类的子类的实例对象
grandson = grandson_class()#生成一个子类的子类的实例对象
name = grandson.name#子类直接去访问父类的父类的类变量并打印,
#结果无误,说明,我们除了继承父类的变量,还继承所有父类的父类,链条式。
print("子类访问基类变量:",name)
grandson.log()#子类调用父类的父类的方法,同理可得,子类也继承父类的父类的所有方法
grandson.public_func()#子类可以直接修改父类的父类也就是基类的方法
########输出结果如下###############
父类访问自身类变量: 父类
father_class
未修改
子类访问父类变量: 父类
father_class
子类访问自己的类变量: 子类
son_class
子类修改父类方法
子类访问基类变量: 父类
father_class
子类修改基类方法

以上代码是一个简单的单继承概括,从代码中,可以看到,当一个类继承自另一个类,那么它将拥有父类的一切数据,包括父类变量,父类的实例变量,以及父类方法,这个方法包括类方法和实例方法。同时,子类的作用就是对父类的扩充,也就是说它可以对父类的所有数据增加、更改。python是一个多继承语言,有时候我们想同时拥有两个类的方法,那直接继承两个类就可以。简单构造代码如下:

class A(object):
def a(self):
pass
class B(object):
def b(self):
pass
class C(A,B):
pass
c_test = C()
c_test.a()
c_test.b()

  从上面代码中可以看出,C类继承自A,B两个类,所以它既可以调用A的方法,又可以调用B的方法。(ios只能通过协议实现。。差评!!!),多继承的特性和单继承差不多是一样的,但值得注意的是,多继承会涉及到方法重复。那么,这里衍生出一个问题。普通继承与super继承。首先来看一段代码:

class A(object):#这么简单的代码。。我就不解释了
def __init__(self):
print("A")
class B(object):
def __init__(self):
print("B")
class C(A):
def __init__(self):
print("C")
A.__init__(self)
class D(A):
def __init__(self):
print("D")
A.__init__(self)
class E(B,C):
def __init__(self):
print("E")
B.__init__(self)
C.__init__(self)
class F(D,E):
def __init__(self):
print("F")
E.__init__(self)
D.__init__(self)
a = E()
print("---------")
b = F()
######看一下输出记录,为了省地儿,我合成了两行行########
# 初始化E类得到的输出结果 E B C A
#---------
# 初始化F类得到的输出结果 F E B C A D A

    分析一下上面的代码,A,B都直接继承于基类,分别有自己的初始化方法,在初始化的时候输出自己的类名。C,D皆继承自A,改写它们的初始化方法,使其在初始化的时候不仅输出自己类名,同时调用一下自己父类的初始化方法即同时输出自己的父类名.E,F两个类为多重继承。来查看一下初始化E类的结果,没有异常,它初始化了自己,也调用了父类的初始化方法,同时调用了父类的父类的初始化方法。再看一下F类的初始化结果。问题来了。它输出了两个A。由此可以分析出。它调用了两次A类的初始化方法,这是代码中极为不愿意看到的。让我们来分析一下代码,看这个问题是如何出现的。首先F继承自D,E两个类。而D继承自A,E继承自B,C。再往上分析,B继承自基类。而C继承自A。问题在这,每继承一个类,我们都对其进行了初始化方法调用。也就是说在F中我们调用了两次A的初始化方法,所以输出了两次。在实际运用中,我们也会遇到这个问题。那就是在多重继承中,常常由于类的关系复杂而使某些父类方法被其子类或者其子类的子类或者在子类重复调用。所以,我们要用到一个关键字super来解决这个问题,代码如下:

class A(object):#代码都差不多。。这个也不解释了。。
def __init__(self):
print("A")
super(A,self).__init__()
class B(object):
def __init__(self):
print("B")
super(B, self).__init__()
class C(A):
def __init__(self):
print("C")
super(C, self).__init__()
class D(A):
def __init__(self):
print("D")
super(D, self).__init__()
class E(B,C):
def __init__(self):
print("E")
super(E, self).__init__()
class F(D,E):
def __init__(self):
print("F")
super(F, self).__init__()
a = E()
print("---------")
b = F()
######看一下输出记录,为了省地儿,我合成了两行行########
# 初始化E类得到的输出结果 E B C A
#---------
# 初始化F类得到的输出结果 F D E B C A

  如上,对比一下两份代码,不难看出super的作用,首先它自动查找父类的初始化方法并调用,同时保证只被调用一次,而且严格按照类继承路线走,关于最后一点可以对比一下两次代码的输出顺序,这个顺序涉及到python的多继承顺序算法,别管它了。除了初始化方法,对于其他方法,super也有同样的作用,需要注意的是,super只针对新式类。在单继承中,super大概被用于偷懒扩充父类构造方法。但是!混用super类和普通继承类比较危险,所以单继承个人很少使用。

以上,继承的问题基本谈完,最后说一下装饰器在类方法中的使用代码如下:

class test(object):#定义一个类。。不要管名字了
name = "test"#类变量
def __init__(self,age):#初始方法,传个参数
self.age = age#定义一个实例变量,把传进来的参数直接赋值给它
def say(self):# 未加装饰器的普通方法,输出个test,ps:只能实例化之后通过实例调用
print("test")
@staticmethod#加装饰器@staticmethod之后的方法,
#即静态方法 不无需实例化调用 ,无法传参数。当一个类只有静态方法的时候,从意义上讲就单纯是一个类的工具包
def say2():
print("say hi 2")
@classmethod
# 类方法 ,不需要实例化即可调用,可以使用类参数,无法使用实例参数,这里没有传个参数做例子。。抱歉
def say3(self):
print("say hi 3")。
@property #加@property的方法
#可以返回数据,使用意义上来讲,就是把经过类方法处理后的数据传递出去
def say4(self):
# print("this is 4")
return "test"

  以上是python中类的一些简单注意事项,做为面向对象的一大重点,类这一概念还有很多值得深究的东西。例如参数类型等等,这些都需要自己去慢慢探究。

也说python的类--基于python3.5的更多相关文章

  1. python基础知识——基于python3.6

    语法糖 # # -*- coding: utf-8 -*- # #------------- # #--------- 语法糖--------------- # #------------------ ...

  2. Python基础-类

    Python基础-类 @(Python)[python, python基础] 写在前面 如非特别说明,下文均基于Python3 摘要 本文重点讲述如何创建和使用Python类,绑定方法与非绑定方法的区 ...

  3. python基础系列教程——Python3.x标准模块库目录

    python基础系列教程——Python3.x标准模块库目录 文本 string:通用字符串操作 re:正则表达式操作 difflib:差异计算工具 textwrap:文本填充 unicodedata ...

  4. python:类的基本特征------继承、多态与封装

    一.继承 1,什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 cl ...

  5. Python菜鸟之路:Python基础-类(1)——概念

    什么是类? 在python中,把具有相同属性和方法的对象归为一个类(class).类是对象的模板或蓝图,类是对象的抽象化,对象是类的实例化.类不代表具体的事物,而对象表示具体的事物. 类的创建 cla ...

  6. Golang、Php、Python、Java基于Thrift0.9.1实现跨语言调用

    目录: 一.什么是Thrift? 1) Thrift内部框架一瞥 2) 支持的数据传输格式.数据传输方式和服务模型 3) Thrift IDL 二.Thrift的官方网站在哪里? 三.在哪里下载?需要 ...

  7. Sublime Text 2 (for OS X )配置成可以运行基于python3解释器的 .py文件

    Mac自带的python 其version是python 2.7 官网下的Sublime Text 2部署好了以后默认也是 为了使ST2 可以在command+B时可以运行基于python3的.py, ...

  8. [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)

    星期一, 20. 八月 2018 01:53上午 - beautifulzzzz 1.前言 做类似zigbee.ble mesh...无线网络节点性能测试的时候,手动操作然后看表象往往很难找出真正的原 ...

  9. 基于Python3的漏洞检测工具 ( Python3 插件式框架 )

    目录 Python3 漏洞检测工具 -- lance screenshot requirements 关键代码 usage documents Any advice or sugggestions P ...

随机推荐

  1. linux安装maven

    一.下载maven 最新地址在:http://maven.apache.org/download.cgi 我下载的是:apache-maven-3.3.9-bin.tar.gz,是已经编译好的包 解压 ...

  2. 【原】作为前端需要了解的B/S架构

    其实B/S架构是属于后台方面的东西,不过作为一个前端,也是需要了解一下滴 C/S架构简要介绍 在了解什么是B/S架构之前,我们有必要了解一下什么是C/S架构: C/S架构是第一种比较早的软件架构,主要 ...

  3. [Unreal]学习笔记之灯光说明

    利用灯光通道,实现局部照亮效果 没有更改Channel之前的效果: 需要将网格物体设置为可移动 将灯光和被照亮物体的Channel设置为同样并且非0零: 设置成功后,就可以实现局部照亮

  4. 为什么现在更多需要用的是 GPU 而不是 CPU,比如挖矿甚至破解密码?

    作者:Cascade链接:https://www.zhihu.com/question/21231074/answer/20701124来源:知乎著作权归作者所有,转载请联系作者获得授权. 想要理解G ...

  5. 第4天--linux内核学习

    驱动使用方式1.编译到内核中 * make uImage进入到系统后mknod /dev/led c 500 0 创建设备节点 2.编译为模块 M make module进入到系统后 mknod /d ...

  6. linux 命令 之判断表达式

    摘自http://www.comptechdoc.org/os/linux/usersguide/linux_ugshellpro.html Tests There is a function pro ...

  7. Python-pandas

    Python-pandas Python 中处理时间序列的主要工具是 pandas 库. 1.pannas 基础 1.1使用 DataFrame 类的第一步 #!/etc/bin/python #co ...

  8. Spring4读书笔记(1)-模块

    Srping主要模块 Core Container spring-core,spring-beans: 提供基础功能,包括IoC和DI等特性.对依赖起到解耦作用(BeanFactory). sprin ...

  9. C语言(Linux)中常用到的函数

    在接触Linux C之前,我比较少用到的函数,都会记录在这里.(持续更新中……) 在学习malloc()函数原理性实现时, size_t:是一种数据类型,标准C库中定义的一种类型,近似于unsigne ...

  10. WebApp开发之--"rem"单位

    随着web app的兴起,rem这是个低调的css单位,近一两年开始崭露头角,有许多朋友对于它的评价不一,有的在尝试使用,有的在使用过程中遇到坑就弃用了.但是我认为rem是用来做web app它绝对是 ...