类的成员

类的成员可以分为三大类:字段、方法和属性

注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份。

一、字段

字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,

普通字段属于对象

静态字段属于类

#!/usr/bin/env python3
#coding:utf8
class Person(object):
country = '静态字段' def __init__(self,name):
self.name = name
#name是普通字段 #访问静态字段
print(Person.country)
#访问普通字段
obj = Person('liuyao')
print(obj.name)

【普通字段需要通过对象来访问】【静态字段通过类访问】

静态字段在内存中只保存一份

普通字段在每个对象中都要保存一份

应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

二、方法

方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;

类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;

静态方法:由类调用;无默认参数;

#!/usr/bin/env python3
#coding:utf8 class Foo(object):
def __init__(self, name):
self.name = name
def ord_func(self):
""" 定义普通方法,至少有一个self参数 """
print (self.name)
print ('普通方法')
@classmethod
def class_func(cls):
""" 定义类方法,至少有一个cls参数 """
print ('类方法')
@staticmethod
def static_func():
""" 定义静态方法 ,无默认参数"""
print ('静态方法')
# 调用普通方法
f = Foo('liuyao')
f.ord_func() # 调用类方法
Foo.class_func() # 调用静态方法
Foo.static_func()

相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

不同点:方法调用者不同、调用方法时自动传入的参数不同。

三、属性  

Python中的属性其实是普通方法的变种。

对于属性,有以下三个知识点:

属性的基本使用

属性的两种定义方式

1、属性的基本使用

#!/usr/bin/env python3
#coding:utf8
# ############### 定义 ###############
class Foo(object): def func(self):
print('func')
# 定义属性
@property
def prop(self):
print('属性')
# ############### 调用 ###############
foo_obj = Foo()
foo_obj.func()
foo_obj.prop #调用属性

由属性的定义和调用要注意一下几点:

定义时,在普通方法的基础上添加 @property 装饰器;

定义时,属性仅有一个self参数

调用时,无需括号

       方法:foo_obj.func()
属性:foo_obj.prop

注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象

    属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。

实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:

根据用户请求的当前页和总数据条数计算出 m 和 n

根据m 和 n 去数据库中请求数据

类的成员修饰符

公有成员,在任何地方都能访问

私有成员,只有在类的内部才能方法

私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线。(特殊成员除外,例如__init__、__call__、__dict__等)

例如:

class C(object):
def __init__(self):
self.name = '公有字段'
self.__foo = "私有字段"

静态字段

公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
私有静态字段:仅类内部可以访问;

公有类:

#!/usr/bin/env python3
#coding:utf8 class Person(object):
name = "公有字段属性"
def __init__(self):
pass
def one(self):
print(self.name)
class Child(Person):
def two(self):
print(self.name)
#类访问
print(Person.name)
obj = Person()
#类的内部访问
obj.one() ch = Child()
#子类可以访问
ch.two()

私有字段

class Person(object):
__name = '私有字段'
def __init__(self):
pass
def one(self):
print(self.__name)
class Child(Person):
def two(self):
print(Person.__name)
#类访问
print(Person.__name)
报错:
print(Person.__name)
ttributeError: type object 'Person' has no attribute '__name' #类的内部访问
obj = Person()
obj.one()
结果:
私有字段
#子类访问
obj = Child()
obj.two()
报错:
print(Person.__name)
AttributeError: type object 'Person' has no attribute '_Child__name'

公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问

私有普通字段:仅类内部可以访问;

ps:如果想要强制访问私有字段,可以通过 【对象._类名__私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员。

公有字段访问:

class Person(object):
def __init__(self):
self.name = '刘耀'
def one(self):
print(self.name)
class Child(Person):
def two(self):
print(self.name)
obj = Person()
#通过类访问
print(obj.name)
#通过内部访问
obj.one()
#子类访问
objj = Child()
objj.two()

私有类访问:

class Person(object):
def __init__(self):
self.__name = '刘耀'
def one(self):
print(self.__name)
class Child(Person):
def two(self):
print(self.__name)
obj = Person()
#通过类访问
print(obj.__name)
#通过内部访问
obj.one()
#子类访问
objj = Child()
objj.two()

方法、属性的访问于上述方式相似,即:私有成员只能在类内部使用

类的特殊成员

1.__doc__

表示类的描述信息

class Person(object):
__doc__ = '这是一条描述信息'
def __init__(self):
pass
obj = Person()
print(obj.__doc__)
结果:
这是一条描述信息

2. moduleclass

  __module__ 表示当前操作的对象在那个模块

  __class__ 表示当前操作的对象的类是什么

1.定义一个模块
#!/usr/bin/env python3
#coding:utf8
class Person(object):
def __init__(self):
self.name = 'liuyao'
2.引入上一个模块
from day8.clstest import Person obj = Person()
print(obj.__class__)
print(obj.__module__)
结果:
<class 'day8.clstest.Person'>
day8.clstest

3. __init__

  构造方法,通过类创建对象时,自动触发执行。

class Person(object):
def __init__(self,name):
self.name = name
print(self.name) obj = Person('liuyao')
# 自动执行类中的 __init__ 方法

4. __del__

  析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

class Person(object):
def __del__(self):
pass

5. __call__

  对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Person(object):
def __init__(self):
passw
def one(self):
print('one')
def __call__(self, *args, **kwargs):
print('call') obj = Person()
obj.one() #执行one方法
obj() #执行__call__w

6. __dict__

类或对象中的所有成员
类的普通字段属于对象;类中的静态字段和方法等属于类, class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def func(self):
print(self.name)
print(self.age)
#类的成员
print(Person.__dict__)
#对象的成员
obj = Person('liuyao','18')
print(obj.__dict__)

7. __str__

  如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

class Person(object):
def __init__(self):
pass #如果不加str那么返回的是
obj = Person()
print(obj)
结果:
<__main__.Person object at 0x0000000000DA6DD8>
如果加了 class Person(object):
def __init__(self):
pass
def __str__(self):
return '我是一个萌萌的类'
obj = Person()
print(obj)
结果:
我是一个萌萌的类

8、__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

class Foo(object):

	def __getitem__(self, key): #获取
print ('__getitem__',key) def __setitem__(self, key, value):#设置
print ('__setitem__',key,value) def __delitem__(self, key):#删除
print ('__delitem__',key)
obj = Foo() result = obj['k1']
obj.__setitem__('k2','v2')
del obj['k1']
结果:
__getitem__ k1
__setitem__ k2 v2
__delitem__ k1

9、__getslice__、__setslice__、__delslice__

该三个方法用于分片操作,如:列表

#!/usr/bin/env python
# -*- coding:utf-8 -*-
class Foo(object): def __getslice__(self, i, j):
print '__getslice__',i,j def __setslice__(self, i, j, sequence):
print '__setslice__',i,j def __delslice__(self, i, j):
print '__delslice__',i,j obj = Foo() obj[-1:1] # 自动触发执行 __getslice__
obj[0:1] = [11,22,33,44] # 自动触发执行 __setslice__
del obj[0:2] # 自动触发执行 __delslice__

10. __iter__

class Foo(object):
def __init__(self,num):
self.num = num
def __iter__(self):
return iter(self.num) obj = Foo([11,22,33,44]) for i in obj:
print (i)

其他技巧

1.isinstance(obj, cls)

检查是否obj是否是类 cls 的对象

class Foo(object):
def __init__(self):
pass obj = Foo()
print(isinstance(obj,Foo))
结果:
True

2.issubclass(sub, super)

检查sub类是否是 super 类的派生类

class Foo(object):
def __init__(self):
pass
class Child(Foo):
pass
print(issubclass(Child,Foo))
结果:
True

异常处理

1、异常基础

案例:

num1 = input('num1:')
num2 = input('num2:')
try:
num1 = int(num1)
num2 = int(num2)
result = num1 + num2
except Exception as e:
print(e)
#当我输入的都是数字的时候,不异常
#当我输入有一个是非数字的时候 打印异常
结果:
num1:1
num2:m
invalid literal for int() with base 10: 'm'

2.异常种类

1)常用异常

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的 2)更多异常 ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError

案例:

IndexError

dic = ["liuyao", '18']
try:
dic[2]
except IndexError as e:
print (e)
#因为没有索引是2的打印异常
list index out of range

KeyError

dic = {'k1':'v1',}
try:
dic['k2']
except KeyError as e:
print(e)

ValueError

s1 = 'hello'
try:
int(s1)
except ValueError as e:
print (e)
结果:
invalid literal for int() with base 10: 'hello'

对于上述实例,异常类只能用来处理指定的异常情况,如果非指定异常则无法处理。

例如:

s1 = 'hello'
try:
int(s1)
except IndexError as e:
print (e)
#他本来应该是valueerror的错误 当定义indexerror的时候 捕捉不到

未捕获到异常,程序直接报错

如果要考虑出现的多个异常情况的话 可以:

s1 = 'hello'
try:
int(s1)
except IndexError as e:
print (e)
except KeyError as e:
print (e)
except ValueError as e:
print (e)
结果:
invalid literal for int() with base 10: 'hello'

万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,即:

s1 = 'hello'
try:
int(s1)
except Exception as e:
print(e)
结果:
invalid literal for int() with base 10: 'hello'

对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行。

s1 = 'hello'
try:
int(s1)
except KeyError as e:
print ('键错误')
except IndexError as e:
print ('索引错误')
except Exception as e:
print ('错误')

3、异常其他结构

try:
# 主代码块
pass
except KeyError as e:
# 异常时,执行该块
pass
else:
print('else')
# 主代码块执行完,执行该块
pass
finally:
# 无论异常与否,最终执行该块
print('finally')
pass
结果:
else
finally

4、主动触发异常

try:
raise Exception('错误了。。。')
except Exception as e:
print (e)
结果:
错误了

5、自定义异常

class Liuyaoerror(Exception):
def __init__(self, msg):
self.message = msg def __str__(self):
return self.message
try:
raise Liuyaoerror('我的异常')
except Liuyaoerror as e:
print (e)

6、断言

# assert 条件

assert 1 == 1

assert 1 == 2

反射

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

class Foo(object):

	def __init__(self):
self.name = 'liuyao' def func(self):
return 'func'
def niubi(self):
return 'niubi'
obj = Foo()
#### 检查是否含有成员 ####
a=hasattr(obj, 'name')
b=hasattr(obj, 'func')
print(a,b)
结果:
True True
如果不存在那么
False
#### 获取成员 ####
print(getattr(obj, 'name'))
print(getattr(obj, 'func'))
结果:
liuyao
<bound method Foo.func of <__main__.Foo object at 0x004DB350>>
如果要获取到并且执行方法:
print(getattr(obj, 'func')())
结果:
我的func
##### 设置成员 ####
setattr(obj, 'age', 18)
setattr(obj, 'show', lambda num: num + 1)
print(getattr(obj, 'age'))
print(getattr(obj, 'show'))
结果:
18
<function <lambda> at 0x004856A8>
# # #### 删除成员 ####
delattr(obj,'name')
# delattr(obj,'func')
print(getattr(obj, 'name'))
结果:
因为self.name在内存中已经被删除
所以:
print(getattr(obj, 'name'))
AttributeError: 'Foo' object has no attribute 'name'

9.Python笔记之面向对象高级部分的更多相关文章

  1. 8.python笔记之面向对象基础

    title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...

  2. Python:笔记(3)——面向对象编程

    Python:笔记(3)——面向对象编程 类和面向对象编程 1.类的创建 说明:和Java不同的是,我们不需要显示的说明类的字段属性,并且可以在后面动态的添加. 2.构造函数 构造函数的功能毋庸置疑, ...

  3. Python学习笔记捌——面向对象高级编程

    __slots__特殊变量的使用: 由于Python是动态语言,允许先编写类,然后在创建实例的时候添加属性或者方法:而__slots__特殊变量就是,限制往类里添加属性的: 在创建类的时候,使用__s ...

  4. python基础之面向对象高级编程

    面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个"函数"供使用(可以讲多函数中公用的变量封装到对象中) ...

  5. python笔记:#013#高级变量类型

    高级变量类型 目标 列表 元组 字典 字符串 公共方法 变量高级 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 (int) 浮点型(float) 布尔型(bool) ...

  6. Python学习--11 面向对象高级编程

    多重继承 Python里允许多重继承,即一个类可以同时继承多个类: class Mammal(Animal): pass class Runnable(object): def run(self): ...

  7. Python笔记之面向对象

    1.类和对象 #create a class class fruit: def say(self): print "hello, python" if __name__ == &q ...

  8. python笔记4:高级特性

    4 高级特性 4.1  切片 [:] *注:-- list和tuple,字符串都支持切片 4.2 迭代 Iteration for ... in 及 for ... in if 两个变量迭代时, 例1 ...

  9. Python基础——7面向对象高级编程

    实例与类动态添加方法 实例添加属性: def Student(object): pass s = Student() s.name = ‘syz’ 实例添加方法 from types import M ...

随机推荐

  1. 【前端】Sublime text3 插件LiveReload 实现实时预览

    1.首先要安装插件LiveReload Sublime text3. 菜单 preferences->packages control,输入install.. 回车,输入LiveReload回车 ...

  2. spring 第一篇(1-1):让java开发变得更简单(下)

    切面(aspects)应用 DI能够让你的软件组件间保持松耦合,而面向切面编程(AOP)能够让你捕获到在整个应用中可重用的组件功能.在软件系统中,AOP通常被定义为提升关注点分离的一个技术.系统由很多 ...

  3. 洛谷P1136 迎接仪式

    题目描述 LHX教主要来X市指导OI学习工作了.为了迎接教主,在一条道路旁,一群Orz教主er穿着文化衫站在道路两旁迎接教主,每件文化衫上都印着大字.一旁的Orzer依次摆出“欢迎欢迎欢迎欢迎……”的 ...

  4. 轻量级应用开发之(01)第一个IOS程序

    一 IPhone轻量级开发 1. 开发环境 Mac 版本: OS X EICap 10.11.3 (15D21) XCode开发版本: Version 7.2.1 (7C1002) 2.简单分析 UI ...

  5. android button 函数调用栈

    Button button=(Button) findViewById(R.id.button);button.setOnClickListener(new Button.OnClickListene ...

  6. Centos是什么

    Linux是GNU/Linux的缩写,通常指各种Linux发行版的通称. 常见的Linux厂家主要有Redhat/Novell等. Redhat有两大Linux产品系列,其一是免费的Fedora Co ...

  7. c3p0配置详解

    数据库连接池C3P0框架是个非常优异的开源jar,高性能的管理着数据源,这里只讨论程序本身负责数据源,不讨论容器管理. 一.实现方式: C3P0有三种方式实现: 1.自己动手写代码,实现数据源 例如: ...

  8. spark中操作hdfs

    1 获取路径 val output = new Path("hdfs://master:9000/output/"); val hdfs = org.apache.hadoop.f ...

  9. hdu 2160 母猪的故事(睡前随机水一发)(斐波那契数列)

    解题思路: 一只母猪生下第二头后立马被杀掉,可以这样想即,生下第二头便被杀掉,可以看成母猪数量没变 第一天 1 第二天 2 第三天 3 :第一头生第二头后杀掉还是1头,第二头再加上第二头生下的,一共三 ...

  10. ls -alrth 及ls 详解

    idcdpi  抓包过程中 用了命令  ls   - alrth :命令,所以回头重新学习 ls命令 linux ls和 ll 命令 标签: linuxsocketssolarisbash出版扩展 2 ...