Python 面向对象 中高级
类成员:
#字段 (也称为:属性) 静态字段 属于类 执行 既可以通过对象访问,也可以通过类访问
普通字段 属于对象 执行只能通过对象访问 (即:定义在 __init__方法中的字段)
class Foo:
def __init__(self,name):
# 字段
self.name = name
# 方法
def show(self):
print(self.name)
obj = Foo('alex')
print(obj.name) # 调用字段,后边不需要加括号
obj.show() # 调用方法,后边需要加括号
字段实例:
class Province:
# 静态字段 (类比全局变量)
country = '中国'
def __init__(self,name):
# 普通字段
self.name = name
henan = Province('河南')
hebei = Province('河北')
print(henan.name) # 输出结果:河南 #通过对象访问
print(Province.country) # 输出结果:中国 #通过类访问
print(henan.country) # 输出结果:中国 #通过对象访问
#方法
普通方法 保存在类中,需创建对象,由对象来调用 参数self 代指=>>调用对象
静态方法 保存在类中,不需创建对象,由类直接调用,加@staticmethod装饰器,不需要传self参数
类方法 保存在类中,由类直接调用,加@classmethod装饰器,需传递参数,约定俗成的self参数写法cls 代指=>> 当前类的类名对于静态方法中不需要传递self参数的情况,对比记忆必须传递self参数的,子类继承父类方法时的除了super方式外的第二种方式:fathor.func(self)
# 静态方法
class Foo:
def bar(self):
print('bar')
@staticmethod
def sta():
print('123')
@staticmethod
def stat(a1,a2):
print(a1,a2)
Foo.sta()
Foo.stat(1,2)
# 输出结果:
# 123
# 1 2
# 类方法
class Foo:
def bar(self):
print('bar')
@classmethod
def class_f(cls):
print('我自己的类名')
Foo.class_f() # 通过类直接调用访问
# 输出结果:我自己的类名
# 普通方法,静态方法,类方法的应用场景:
如果对象中需要保存一些值,在执行某功能时,
需要使用对象中的这些值的情况下,使用===》普通方法
不需要使用对象中的任何值的情况下,使用==》静态方法
在方法里边如果需要用到当前类的话,使用==》类方法
# 这里注意下,类方法,其实作用不是很大,可以通过自己构造静态方法,传递参数(类名)来实现。
# 特殊的方法类型 -- 属性 (俗称)
加上@property装饰器,既有字段的特性,又有方法的影子!
# 即:它采用方法的定义格式,字段的调用方式(也就是,调用的时候,不需要加括号。)
class Foo:
@property
def pro(self):
return 1
obj = Foo()r = obj.proprint(r)
# 输出结果:1
# 如何利用@property修改设置pro方法的默认值
class Foo:
# 用于获取值 @property
def pro(self):
return 1 # 用于修改原先方法pro的默认值 下方@pro是方法名 除了支持@pro.setter写法外,还有@pro.delete @pro.setter
def pro(self,val):
print(val)obj = Foo()r = obj.proprint(r)
# 输出结果:1# 重新设置pro的值 obj.pro = 123# 注意:对于@pro.setter 和@pro.delete 其实这里并没有真正重新设置或者删除值,而是改变了对象调用的对应关系,相当于调用了新的方法!
# 那么,属性有什么用呢?
和它的特性一样,采用方法的定义格式,采用字段的调用方式;它没有什么特殊的用处,只是为了书写的时候,简略明了,省去括号。
# 实例: 输入页码 显示分页 练习目的:通过利用属性 减少代码最后调用时,加括号。
# -*- coding: utf-8 -*-
class pagenation:
def __init__(self,current_page):
try:
# 捕捉用户输入的错误格式 (非数字类型)
p = int(current_page)
except Exception as e:
# 出现异常后 返回第1页
p = 1
self.page = p
@property
def start(self):
val = (self.page-1)*10
return val
@property
def end(self):
val = self.page * 10
return val
# 假如说相关数据有1000页
li = []
for i in range(1000):
li.append(i)
while True:
p = input('请输入要查看的页码:') #每页显示10条
# 1页 1,10
# 2页 10,20
# 3页 20,30
obj = pagenation(p)
# 因为类中采用了@property 所以下方调用start和end方法的时候,不需要加括号
print(li[obj.start:obj.end])
# 属性 property 的第二种写法 (即:不调用装饰器)
# -*- coding: utf-8 -*-
class Foo:
def f1(self):
return123
def f2(self,v):
print(v)
def f3(self):
print('del info myself define!')
# 属性 除了@property装饰器写法的另一种写法
per = property(fget=f1,fset=f2,fdel=f3,doc='相关描述')
# 注意:上方property() 括号中,算上doc,最多传递4个参数
# 参数 fget,fset,fdel 分别对应下方的三种调用方式
obj = Foo()
# 1 获取
# ret = obj.per
# print(ret)
# 2 设置
# obj.per = 123456
# 3 删除
del obj.per
# 注意:Python WEB框架 Django 的视图中 request.POST 就是使用的静态字段的方式创建的属性
class WSGIRequest(http.HttpRequest):
def __init__(self, environ):
script_name = get_script_name(environ)
path_info = get_path_info(environ)
if not path_info:
# Sometimes PATH_INFO exists, but is empty (e.g. accessing
# the SCRIPT_NAME URL without a trailing slash). We really need to
# operate as if they'd requested '/'. Not amazingly nice to force
# the path like this, but should be harmless.
path_info = '/'
self.environ = environ
self.path_info = path_info
self.path = '%s/%s' % (script_name.rstrip('/'), path_info.lstrip('/'))
self.META = environ
self.META['PATH_INFO'] = path_info
self.META['SCRIPT_NAME'] = script_name
self.method = environ['REQUEST_METHOD'].upper()
_, content_params = cgi.parse_header(environ.get('CONTENT_TYPE', ''))
if 'charset' in content_params:
try:
codecs.lookup(content_params['charset'])
except LookupError:
pass
else:
self.encoding = content_params['charset']
self._post_parse_error = False
try:
content_length = int(environ.get('CONTENT_LENGTH'))
except (ValueError, TypeError):
content_length = 0
self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
self._read_started = False
self.resolver_match = None
def _get_scheme(self):
return self.environ.get('wsgi.url_scheme')
def _get_request(self):
warnings.warn('`request.REQUEST` is deprecated, use `request.GET` or '
'`request.POST` instead.', RemovedInDjango19Warning, 2)
if not hasattr(self, '_request'):
self._request = datastructures.MergeDict(self.POST, self.GET)
return self._request
@cached_property
def GET(self):
# The WSGI spec says 'QUERY_STRING' may be absent.
raw_query_string = get_bytes_from_wsgi(self.environ, 'QUERY_STRING', '')
return http.QueryDict(raw_query_string, encoding=self._encoding)
# ############### 看这里看这里 ###############
def _get_post(self):
if not hasattr(self, '_post'):
self._load_post_and_files()
return self._post
# ############### 看这里看这里 ###############
def _set_post(self, post):
self._post = post
@cached_property
def COOKIES(self):
raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '')
return http.parse_cookie(raw_cookie)
def _get_files(self):
if not hasattr(self, '_files'):
self._load_post_and_files()
return self._files
# ############### 看这里看这里 ###############
POST = property(_get_post, _set_post)
FILES = property(_get_files)
REQUEST = property(_get_request)
所以,定义属性共有两种方式,分别是【装饰器】和【静态字段】,而【装饰器】方式针对经典类和新式类又有所不同。
# python 成员修饰符
公有成员
私有成员
__字段名 __方法名
无法直接访问,可以通过在类内部自定义方法,间接访问。
普通字段的私有属性
静态字段的私有属性
普通方法私有性
同理,静态方法同样有私有属性
对于子类继承父类的情况,子类无法直接访问父类中的私有方法和字段,因为私有属性的私有性是相对于字段所属的类来讲的,也就是说,私有方法和私有字段只能通过所在的类内部访问调用。
# 特殊成员
类后边加()自动调用执行__init__ 方法
对象后边加()自动调用执行__call__方法
加减乘除
析构方法
只要对象在内存中,被垃圾回收机制找到销毁的时候,Python内部就会自动触发,执行析构方法。
__dict__ 通过字典的形式,将对象或者类的成员显示出来。
__getitem__ 实现通过索引取值
__setitem__ 实现类似列表通过索引赋值的方法
__delitem__ 实现类似列表通过索引删除相关值的方法
上述方法 没有加逻辑之前,仅仅和下方对应的相关调用语句是一一对应关系,并没有真正的修改和删除。
单例模式
Python 面向对象 中高级的更多相关文章
- python 面向对象初级篇
Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...
- Python 面向对象 基础
编程范式概述:面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现 ...
- python面向对象进阶(八)
上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- python 面向对象(进阶篇)
上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- Python面向对象详解
Python面向对象的"怜人之处" Python的待客之道--谁能进来 Python的封装--只给你想要的 Python的继承--到处认干爹 Python的多态--说是就是
- python 面向对象和类成员和异常处理
python 面向对象 你把自己想象成一个上帝,你要创造一个星球,首先你要把它揉成一个个球,两个直径就能创造一个球 class star: '''名字(name),赤道直径(equatorial di ...
- python 面向对象学习
------Python面向对象初 下面写一个类的简单实用,以便方便理解类 #python 3.5环境,解释器在linux需要改变 #阅读手册查询readme文件 #作者:S12-陈金彭 class ...
- 初识python面向对象
一.初识python面向对象: class Person: #使用class关键字定义一个类 age=0 #类变量(静态变量) def eat(self,food): #定义一个方法 self.age ...
随机推荐
- C语言基于GTK+Libvlc实现的简易视频播放器(二)
简易视频播放器-全屏播放 一.课程说明 上一次我们使用gtk+libvlc实现了一个最简单的视频播放器,可以实现点击按钮暂定和停止播放视频,以及同步显 示视频播放进度,但即使作为一个视频播放器,只有这 ...
- CentOS 6.6安装Xtrabackup RPM提示缺少libev.so.4()
在CentOS Release 6.6安装percona-xtrabackup-2.3.4时,遇到下面错误信息 rpm -ivh percona-xtrabackup-2.3.4-1.el6.x86_ ...
- eclipse svn账号更换
在eclipse下用 svn的时候,我们习惯将用户名和密码保存.前天公司将svn的账号全部更换了,这时原来的eclipse保存的svn账号密码就失效了.那怎么样才能切换账号了,eclipse svn插 ...
- redis、memcache、mongoDB 做了对比
from: http://yang.u85.us/memcache_redis_mongodb.pdf 从以下几个维度,对redis.memcache.mongoDB 做了对比. 1.性能 都比较 ...
- 用javascript插入样式
一.用javascript插入<style>样式 有时候我们需要利用js来动态生成页面上style标签中的css代码,方法很直接,就是直接创建一个style元素,然后设置style元素里面 ...
- spring3.0+mybatis+spring快速入门
一.首先奉上项目目录结构: 说明: dao,mapping,model包下的所有内容可以使用Generator工具自助生成. 具体用法,可以网上学习一下,比较简单,主要做以下工作: 1.提供相关的数据 ...
- BZOJ 3112: [Zjoi2013]防守战线 [单纯形法]
题目描述 战线可以看作一个长度为n 的序列,现在需要在这个序列上建塔来防守敌兵,在序列第i 号位置上建一座塔有Ci 的花费,且一个位置可以建任意多的塔,费用累加计算.有m 个区间[L1, R1], [ ...
- struts之类型转换
Struts2的内置类型转换器: Struts2的内置类型转换器,可以为你处理大多数的类型转换,这包括了以下类型和String类型之间的转换! 1.String 将int,double,boolean ...
- 当Python在appium中使用if……else语句不好使怎么办
前几天写自动化脚本的时候,有个地方需要用if--else判断获得的ID和name是哪个,从而决定点击哪个按钮,我用if--else去判断,可是总是提示我找不到对应的元素, 在网上爬了好久,最终终于找到 ...
- HTML 学习笔记 JavaScript (String)
String对象用于存储字符串的数据.这里我们做了JavaScript的String字符串对象常用操作总结. 创建String对象的方式 声明:String 对象的方法也可以在所有基本字符串值中访问到 ...