·类(Class)

笔记:

  Python是一种面向对象(Object Oriented)的编程语言,类(Class)是Python的核心概念。在Python中,不管是列表、字符串、函数和类都是对象。

  在面向对象编程(OOP)中,任何一个对象都要包含两个部分:属性(是什么)和方法(能做什么)

举个例子:小红有某些特征:眼睛大、皮肤白、身材好,这些特征可以比作类中属性;除了特征之外,小红会唱歌、跳舞、弹琴,这些能力可以比作类中的方法:

def 美女:
眼睛 = 大
皮肤 = 白
身材 = 好
唱歌()
跳舞()
弹琴()

将美女类实例化:

小红 = 美女()  #小红是一个实例

针对”小红“这个实例,访问属性和使用方法:

小红.眼睛        #访问类中的属性
小红.眼睛 = 小 #修改类中的属性(眼睛由大变小)
小红.唱歌() #使用类中的方法

@类中的基本概念


 创建一个Hello类:

class Hello(object):                     #在python3中,所有类都是类object的子类;定义类也可以写成 class Hello:或者 class Hello():
def __init__(self,name='world'): #初始化函数__init__
self.name = name #类中的属性
def get_name(self): #类中的函数称作方法。
return 'hello,{}'.format(self.name) h = Hello('jimmy') #实例化类(h是实例对象)
print(h.name) #访问类的属性
print(h.get_name()) #访问类的方法
print('显示h是Hello的实例:',type(h))
print('显示h是Hello的实例:',h.__class__)
print('显示h是Hello的实例,类Hello在内存中的地址为(at···):',h)
打印结果:
jimmy
hello,jimmy
显示h是Hello的实例: <class '__main__.Hello'>
显示h是Hello的实例: <class '__main__.Hello'>
显示h是Hello的实例,类Hello在内存中的地址为(at···): <__main__.Hello object at 0x000001A057CE6CC0>

初始化函数: __init__

初始化函数意味着实例化时要给name提供一个值,通过__init__执行初始化,让实例具有name的属性。由于类Hello中name参数设有默认值,当没有传入参数时,默认为world。

在类外,字符串 'Jimmy' 通过初始化函数__init__()中的 name 参数存入内存中,以Hello类型存在,组成一个对象,这个对象和变量h建立引用关系。这个过程也可以理解成这些数据附加到一个实例上,这样就能通过实例以访问属性的方式访问它。

类中的: Self

在类中, 如果某个地方(比如类中的方法)想要使用实例化传入的数据,那该怎么办?

在类中,将所有传入数据都赋值给一个变量,这个变量是在初始化函数__init__中的第一个参数self。它能接收实例化过程中传入的所有数据,这些数据是根据初始化函数后面的参数导入的。很显然,self就是一个实例,准确说法是应用实例,因为它所对应的就是具体的数据。接下来来验证:

class Hello(object):
def __init__(self,name='world'):
self.name = name
     self.address = 'beijing'
print(self)
print(type(self))
def get_name(self):
return 'hello,{}'.format(self.name) h = Hello()
打印结果:
<__main__.Hello object at 0x0000019FBBBB4E10>
<class '__main__.Hello'>

self实例和h实例一样都有属性。self.name是self的属性,值为name,当然也可以写成self.xxx = name也是可以的。self属性的值不一定要从外部传入,也可以在初始化函数中定义,比如self.address = 'beijing'

在get_name(self)方法中,self是默认的,当类实例化后调用此方法,不需要赋值self能够让return中的语句访问初始函数中传入的值和属性)

类提供默认的行为,而实例可以看成一个工厂。所谓工厂就是可以用一个模板作出很多产品,而类就是模板,实例就是具体的产品。

@类属性和实例属性


类是一个对象,有属性;同样,类实例化后也是一个对象,也有它的属性。通过实例化得到的属性称为实例属性,一般情况下可以通过类来访问属性,也可以通过实例来访问属性。

class A:
x = 1 a = A()
a.x = 5 #更改实例属性
print('实例属性为:',a.x)
print('类属性为:',A.x)
打印结果:
实例属性为: 5
类属性为: 1

实例属性更改了,但类属性没有跟着改变,这是因为类属性不会受实例属性所左右。

class A:
x = 1 a = A()
A.x = 10 #更改类属性
print('实例属性为:',a.x)
print('类属性为:',A.x)
打印结果:
实例属性为: 10
类属性为: 10

类属性更改了,实例属性也跟着改变了,说明实例属性受类属性所左右。

以上所言是指类中的变量引用的是不可变的数据类型(整型、浮点型、字符串、元组),如果引用可变数据类型(字典、列表),数据将发生变化:

class B:
x = [1,2,3,4] b = B()
b.x.append(5) #实例属性增加一个值5
print('实例属性:',b.x)
print('类属性:',B.x)
打印结果:
实例属性: [1, 2, 3, 4, 5]
类属性: [1, 2, 3, 4, 5]

当变量中引用的是可变数据类型时,类属性和实例属性都能够直接修改这个对象,从而影响另一方的值。

通过实例和类增加属性:

class B:
x = [1,2,3,4] b = B()
B.y = 'hello,world!' #增加一个类属性
print('实例属性:',b.y)
打印结果:
实例属性: hello,world!

结果表明:通过类增加一个类属性,实例可以访问到它。

如果是用实例增加一个实例属性呢?

class B:
x = [1,2,3,4] b = B()
b.y = 'hello,world!' #增加一个实例属性
print('实例属性:',b.y)
print('类属性:',B.y)
打印结果:
实例属性: hello,world!
Traceback (most recent call last):
File "test1.py", line 8, in <module>
print('类属性:',B.y)
AttributeError: type object 'B' has no attribute 'y'

结果表明:增加的实例属性可以通过实例访问,如果通过类访问,结果显示类B中没有属性y。

@ 数据流转


在类的应用中,最广泛的是将类实例化,通过实例来执行各种操作。所以对此过程中的数据流转必须弄明白。

class Hello(object):
def __init__(self,name='world'):
self.name = name
def get_name(self):
return 'hello,{}'.format(self.name)
def get_color(self,color):
print('My love color is:',color) h = Hello('jimmy')
print(h.get_name())
print(h.get_color('red'))
打印结果:
hello,jimmy
My love color is: red
None #由于get_color()方法没有设置返回值,函数默认返回None

 数据流转过程:

创建实例 h = Hello('jimmy'),h 实例和初始化函数中self对应(self接收实例传入的所有数据);'jimmy'是具体的数据,通过初始化函数中的name参数传给self.name(self是个实例,可以设置它的属性),此时name的值为jimmy。

类中除初始化函数以外的方法无论有没有定义参数,都要以self开头,这在类中是不能省略的,这表示所有方法都承接self实例对象。也就是实例的属性被带入到每个方法中,如get_name()中的return 'hello,{}'.format(self.name)语句,self.name调用前面已经确定的实例属性数据为jimmy,所以函数返回hello,jimmy。因此,通过self,可以实现数据在类的内部流转。

如果要把数据从类的内部传到外部,可以通过return语句,由于def get_color():方法没有设置函数返回值,函数默认返回None。

@ 类的命名空间和作用域


类命名空间:

定义类时,在class语句中的代码都在一个命名空间中执行,即类的命名空间。命名空间是从所定义的命名到对象的映射集合。不同的命名空间可以同时存在但彼此相互独立。

命名空间因对象不同,可以分为以下几种:

内置命名空间:

内置函数的命名空间都属于内置命名空间,因此,可以在程序中直接运行它们。比如print()函数id()函数等拿来就可以直接使用。

全局命名空间:

每个模块都有自己的全局命名空间,不同模块的全局命名空间彼此独立;不同模块相同名称的命名空间,因为模块不同而不会相互干扰。

本地命名空间:

模块中有类和函数 ,每个类或者函数所定义的命名空间就是本地命名空间。如果函数返回结果或者异常,本地命名空间也将结束。

各个命名空间的关系(图片来源于网络):

访问命名空间的时候,就按照从里到外的顺序:

def Duo(x,y):
name = 'jimmy'
return locals() print(Duo('he','llo'))
打印结果:
{'x': 'he', 'y': 'llo', 'name': 'jimmy'}

通过locals()访问本地命名空间的方法,命名空间中的数据存储结构和字典一样;也可以通过globals()访问全局命名空间。

作用域:是指在python程序中可以直接访问到的命名空间。直接访问意味着访问命名空间中的命名时无需附加任何修饰语。程序按照命名空间从里到外的顺序,搜索相应命名空间能够访问到的作用域。

def out_t():
b = 10
def in_t():
c= 20
a = 30

假设我在def in_t():函数中,c对于我来说就是本地作用域,而a和b不是;如果我在def in_t():函数中新增加一个对象(b = 20),这和def out_t():中的b不会冲突,因为他们的作用域不同。

接下来我们证实:

def out_t():
a = 10
def in_t():
a = 20
print('in_t,a=',a)
in_t()
print('out_t,a=',a) a = 30 print(out_t())
print('a=',a)
打印结果:
in_t,a= 20
out_t,a= 10
None
a= 30

end~

****** 几米花的Python ****** 博客主页:https://www.cnblogs.com/jimmy-share/  欢迎转载 ~

python-类(1)的更多相关文章

  1. Python类中super()和__init__()的关系

    Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...

  2. LightMysql:为方便操作MySQL而封装的Python类

    原文链接:http://www.danfengcao.info/python/2015/12/26/lightweight-python-mysql-class.html mysqldb是Python ...

  3. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  4. python 类以及单例模式

    python 也有面向对象的思想,则一切皆对象 python 中定义一个类: class student: count = 0         books = [] def __init__(self ...

  5. Python类的特点 (1):构造函数与方法

    Python中,类的特点: #encoding:utf-8 class Parent(object): x=1 #x是Parent类的属性(字段) def __init__(self): print ...

  6. Python类属性,实例属性

    1.Python类数据属性:定义在类里面但在函数外面的变量,它们都是静态的. #一段很简单的代码,但反应了很多 >>> class A(): a=1 #一个类里面有个属性a > ...

  7. python类及其方法

    python类及其方法 一.介绍 在 Python 中,面向对象编程主要有两个主题,就是类和类实例类与实例:类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中 ...

  8. python类的定义和使用

    python中类的声明使用关键词class,可以提供一个可选的父类或者说基类,如果没有合适的基类,那就用object作为基类. 定义格式: class 类名(object): "类的说明文档 ...

  9. Python类的探讨

    我们下面的探讨基于Python3,我实际测试使用的是Python3.2,Python3与Python2在类函数的类型上做了改变 1,类定义语法  Python类定义以关键字class开头,一个类定义例 ...

  10. python - 类成员修饰符

    在java,c#类的成员修饰符包括,公有.私有.程序集可用的.受保护的. 对于python来说,只有两个成员修饰符:公有成员,私有成员 成员修饰符是来修饰谁呢?当然是修饰成员了.那么python类的成 ...

随机推荐

  1. 通信与实际用例应用(消息队列和进程撰写的ATM机与消息队列的五子棋对站)

    int semget(key_t key, int nsems, int semflg); 功能:创建信号量或获取信号量 nsems:信号量的数量 semflg: IPC_CREAT|IPC_EXEC ...

  2. Python学习---Python的框架基础学习

    框架基础 框架实质: 所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端 B/S结构的响应: import socket def handle_requ ...

  3. Python学习---django模板继承180123

    django模板继承  --20180123 a.include 模板标签 b.extend(继承)模板标签 ------include 模板标签 该标签允许在(模板中)包含其它的模板的内容. 标签的 ...

  4. Python实例---抽屉热搜榜前端代码分析

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Python学习---装饰器的学习1210

    装饰器的基础 学习前提: 作用域 + 函数的理解 + 闭包  [学习,理解] 代码编写原则: 对修改开放对扩展开放 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前 ...

  6. Linux 下Shell的学习2

    0. 查看帮助(比如内置功能)    man bash    -->变量处理大全 1.-计算变量长度的不同方法及不同方法的耗时对比    尽可能的用内置的命令处理,速度快        time ...

  7. 沉淀,再出发:VUE的简单理解

    沉淀,再出发:VUE的简单理解 一.前言 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架.Vue 只关注视图层,采用自底向上增量开发的设计.Vue 的目标是通过 ...

  8. December 08th 2016 Week 50th Thursday

    Life is a test and this world a place of trial. 人生是一场考试,这个世界就是考场. I have not passed the test yet. I ...

  9. (持续更新) CSS属性持续记录

    可以去除ul的li标签自带的圆点list-style-type: none; 可以将自己的光标改变样式:cursor: pointer;

  10. 包不包含__declspec(dllimport)的判定

    按照MSDN说明,当链接dll的导出函数时,只需要包含头文件和lib,__declspec(dllimport)修饰符不是必须的,但加上该修饰能使导出函数的调用效率更高.那么,究竟原因是什么? 不使用 ...