python-类(1)
·类(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-类(1)的更多相关文章
- Python类中super()和__init__()的关系
Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...
- LightMysql:为方便操作MySQL而封装的Python类
原文链接:http://www.danfengcao.info/python/2015/12/26/lightweight-python-mysql-class.html mysqldb是Python ...
- python 类属性与方法
Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...
- python 类以及单例模式
python 也有面向对象的思想,则一切皆对象 python 中定义一个类: class student: count = 0 books = [] def __init__(self ...
- Python类的特点 (1):构造函数与方法
Python中,类的特点: #encoding:utf-8 class Parent(object): x=1 #x是Parent类的属性(字段) def __init__(self): print ...
- Python类属性,实例属性
1.Python类数据属性:定义在类里面但在函数外面的变量,它们都是静态的. #一段很简单的代码,但反应了很多 >>> class A(): a=1 #一个类里面有个属性a > ...
- python类及其方法
python类及其方法 一.介绍 在 Python 中,面向对象编程主要有两个主题,就是类和类实例类与实例:类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中 ...
- python类的定义和使用
python中类的声明使用关键词class,可以提供一个可选的父类或者说基类,如果没有合适的基类,那就用object作为基类. 定义格式: class 类名(object): "类的说明文档 ...
- Python类的探讨
我们下面的探讨基于Python3,我实际测试使用的是Python3.2,Python3与Python2在类函数的类型上做了改变 1,类定义语法 Python类定义以关键字class开头,一个类定义例 ...
- python - 类成员修饰符
在java,c#类的成员修饰符包括,公有.私有.程序集可用的.受保护的. 对于python来说,只有两个成员修饰符:公有成员,私有成员 成员修饰符是来修饰谁呢?当然是修饰成员了.那么python类的成 ...
随机推荐
- 【Leetcode】【Easy】Isomorphic Strings
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...
- 第六次作业——Excel制作工资表
- Hadoop Spark 基础教程
0x01 Hadoop 慕课网 https://www.imooc.com/learn/391 Hadoop基础 慕课网 https://www.imooc.com/learn/890 Hadoop ...
- [WebKit] JavaScriptCore解析--基础篇 (一)JSC与WebCore
先看一下官方的基本介绍,短短几句就塞满了关键字. SquirrelFish,正式名称是JavaScriptCore,包括register-based(基于寄存器的虚拟机), direct-thread ...
- 简析Chrome和Webkit的渊源
http://www.3lian.com/edu/2012/05-25/28803.html 互联网的浪潮从未停息,而用以网上冲浪的冲浪板也一直在变得愈加精良.自人们进入互联网时代以来,即已经发生了三 ...
- 2763. [JLOI2011]飞行路线【分层图最短路】
Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...
- showDoc项目文档管理工具
1:下载showdoc代码文件 https://github.com/star7th/showdoc https://www.showdoc.cc/help?page_id=14 官方帮助文档 2:安 ...
- mysql 数据增删改查基本语句
增: insert insert into 表名(字段1,字段2,字段3......字段N) values(值1,值2,值3): 如果不申明插入那些字段,则默认所有字段. 如果一次可以插入多条数据 可 ...
- 由于开发需求需要在附件查看页面添加水印,于是网上看到一位大牛写了一个js加水印的方法觉得很实用,也很方便,记录一下,哈哈
大牛的博客链接:https://www.cnblogs.com/daixinyu/p/6715398.html 提供给大家学习 我优化了几点 1,我把水印的样式单独提出来,这样会提高渲染水印的性能 2 ...
- ThinkPHP5入门(四)----模板篇
一.模板访问 1.没有参数传递 $view = new View(); return $view->fetch(); 此时默认访问的模板路径为:[模板文件目录]/当前控制器名(小写+下划线)/当 ...