python's twenty-second day for me 封装,property方法
面对对象的三大特性:继承,多态,封装。
函数和属性装到了一个非全局的命名空间----封装。
封装:
在类中,静态属性,方法,对象属性都可以变成私有的,只需要在这些名字前加上‘__’(双下划线)。
在类内,只要你的代码遇到‘__’(双下划线).名字,就会被python解释器自动转换_类名__名字。
class A:
__N = 'aaa' # 静态变量
def func(self):
print(A.__N) # 在类的内部使用正常 ‘aaa’
print(A.__dict__) # 会以这种形式存储到字典中:{'_A__N': 'aaa'}
# print(A.__N) # 直接在外部调用会报错
# print(A._A__N) # 所以可以使用这种方式调用,但是不能这样调用。
a = A()
a.func()
# 一个私有的名字,在存储的过程中仍然会出现在A.__dict__中,所以我们仍然可以调用到。
# python对其的名字进行了修改:_类名__名字。
# 只不过在类的外部调用: '_类名__名字'去使用。
# 在类的内部可以正常的使用名字调用。
私有的名字不能被子类继承:
class D:
def __func(self): # _D_func
print('in func')
class E(D):
def __init__(self):
self.__func() # 它会找 _E__func 这样的名字。 e = E() # 会报错,因为私有的名字不能被继承,
class D:
def __init__(self):
self.__func() # 在哪个类中定义的名字就会以固定方式存储: _D__func
def __func(self): # _D__func
print('in D')
class E(D):
def __func(self): # _E__func
print('in E')
e = E() # 私有的名字,在类内使用的时候,就是会变成: _该类名__方法名
# 以上为例:没有双下划线会先找E中的func
# 但是有了双下划线,会在调用这个名字的类D中直接找_D__func
面试题
变形只在类的内部发生:
class F:pass
F.__name = 'alex' # 并不是创建私有属性。
print(F.__name)
print(F.__dict__) # {'__name': 'alex'} 并不是私有属性
Java中的对比:
public 共有的 在类的内部可以使用,子类可以使用,外部可以使用 python中所有正常的名字。
prctect 保护的 在类的内部可以使用,子类可以使用,外部不可以使用, python中没有
private 私有的 只能在类的内部使用,子类和外部都不可以使用 python中的 __名字。(双下划线)
私有的用法:
1,当一个方法不想被子类继承的时候。
2,有些属性或者方法不希望从外部被调用,只想提供给内部的方法使用。
@property 能够将一个方法伪装成一个属性。将代码变得更美观。
从原来的对象的对象名.方法名(),变成了对象名.方法名。
class Person:
def __init__(self,name,weight,height):
self.name = name
self.__height = height
self.__weight = weight
@property
def bmi(self):
return self.__weight/self.__height**2
print(Person.__dict__)
p = Person('顾小白',70,1.75)
print(p.__dict__) #{'name': '顾小白', '_Person__weight': 70, '_Person__height': 1.75}
# 被property装饰的bmi仍然是一个方法,存在Person.__dict__
# 对象的.__dict__中不会存储这个属性。 # 在一个类加载的过程中,会先加载这个的名字,包括被property装饰的。
# 在实例化对象的时候,python解释器会先到类的空间里看看有没有这个被装饰的属性。
# 如果有就不能在自己的对象空间中创建这个属性了。
@property ---> func 将方法伪装成属性,只能看,不能对之操作。
@func.setter ---> func 对伪装的属性进行赋值的时候调用这个方法,一般情况用来修改属性。
@func.deleter ---> func 在执行del 对象.func的时候调用这个方法,一般情况用来删除属性,一般不用。
class Person:
def __init__(self,name):
self.__name = name # 私有属性
@property # 将方法装饰成属性使用。 现在 p.name 相当于 p.name()
def name(self):
return self.__name
@name.setter
def name(self,new_name):
if type(new_name) is str: # 类型不对无法替换,防止乱改。
self.__name = new_name # 将new_name 赋值给 self.__name 这一步改变了值。
else:
print('类型不对,无法替换...')
@name.deleter
def name(self):
del self.__name # 删除self.__name属性
p = Person('alex')
print(p.name) # alex
p.name = 'alex_sb'
print(p.name) # alex_sb
del p.name
print(p.name) # 报错:AttributeError: 'Person' object has no attribute '_Person__name'
@classmethod : 类方法,可以直接被类调用,不需要默认传对象参数,只需要传一个类参数就行了。
# 全场改动折扣,不能单个改动。
class Goods():
__discount = 0.8 # 静态属性
def __init__(self,name,origin_price):
self.name = name
self.__price = origin_price
@property
def price(self):
return self.__price * Goods.__discount
@classmethod
def change_discount(cls,new_discount):
cls.__discount = new_discount
Goods.change_discount(1) # 可以在实例化之前使用。
g = Goods('薯片',10)
print(g.price)
staticmethod:
当一个方法要使用对象的属性时,就是使用普通的方法。
当一个方法要使用类中的静态属性时,就是用类方法。
当一个方法要既不使用对象的属性也不使用类中的静态属性时,就可以使用 staticmethod 静态方法。
class Student:
def __init__(self,name):pass
@staticmethod
def login(): # login就是一个类中的静态方法,静态方法没有默认参数,就当成普通函数。
pass Student.login()
python's twenty-second day for me 封装,property方法的更多相关文章
- python's twenty day for me 继承 和 super()方法
super(): 在单继承中就是单纯的寻找父类. 在多继承中就是根据子节点所在图 的mro顺序,找寻下一个类. 遇到多继承和super(): 对象.方法 1,找到这个对象对应的类. 2,将这个类的所有 ...
- Python+Selenium中级篇之-二次封装Selenium中几个方法
本文来介绍,如何把常用的几个webdriver的方法封装到自己写的一个类中去,这个封装过程叫二次封装Selenium方法.我们把打开站点,浏览器前进和后退,关闭和退出浏览器这这个方法封装到一个新写的类 ...
- Python+Selenium中级篇之8-Python自定义封装一个简单的Log类《转载》
Python+Selenium中级篇之8-Python自定义封装一个简单的Log类: https://blog.csdn.net/u011541946/article/details/70198676
- VBA/VB6/VBS/VB.NET/C#/Python/PowerShell都能调用的API封装库
API函数很强大,但是声明的时候比较繁琐. 我开发的封装库,包括窗口.键盘.鼠标.消息等常用功能.用户不需要添加API函数的声明,就可以用到API的功能. 在VBA.VB6的引用对话框中引用API.t ...
- Kong管理UI -kong-dashboard (附kong封装webservice方法)
本文仍然是在centos 6.7的环境下进行 本文转载请注明出处 —— xiaoEight btw如果要正常使用管理UI,前提为kong已经正常run(可参考)起来,此 ...
- 封装和 property方法
封装其实就是一个类用双下划线把自己的属性或者方法给限制住 不让其他的类直接调用或者修改 必须通过这个类来进行操作,这个类通过双下划线__把自己的属性和方法给限制住了 封装就是私有的过程 把父类中的属 ...
- js封装的方法
1.JS封装就是尽量把使用的方式简单化,内部逻辑和使用解耦.通俗的说就是使用的时候只需要知道参数和返回值,其他条件尽量不要使用人员进行设置. 2.JS封装的方法有函数方式.对象的方式.闭包的方式. 举 ...
- Python抓取页面中超链接(URL)的三中方法比较(HTMLParser、pyquery、正则表达式) <转>
Python抓取页面中超链接(URL)的3中方法比较(HTMLParser.pyquery.正则表达式) HTMLParser版: #!/usr/bin/python # -*- coding: UT ...
- Python中模拟enum枚举类型的5种方法分享
这篇文章主要介绍了Python中模拟enum枚举类型的5种方法分享,本文直接给出实现代码,需要的朋友可以参考下 以下几种方法来模拟enum:(感觉方法一简单实用) 复制代码代码如下: # way1 ...
- 合并多个python list以及合并多个 django QuerySet 的方法
在用python或者django写一些小工具应用的时候,有可能会遇到合并多个list到一个 list 的情况.单纯从技术角度来说,处理起来没什么难度,能想到的办法很多,但我觉得有一个很简单而且效率比较 ...
随机推荐
- MyEclipse安装git插件
安装egit插件的步骤(安装egit不成功的原因主要是下载的egit版本不适合当前使用的eclipse版本).先检查自己MyEclipse适用egit的版本. 查看自己MyEclipse版本,如下图: ...
- spring boot MongoDB的集成和使用
前言 上一章节,简单讲解了如何集成Spring-data-jpa.本章节,我们来看看如何集成NoSQL的Mongodb.mongodb是最早热门非关系数据库的之一,使用也比较普遍.最适合来存储一些非结 ...
- uva 11825 巧妙地子集枚举方法
https://vjudge.net/problem/UVA-11825 题目大意,有n台服务器,有n种服务,每台服务器都运行着所有的服务,一台服务器可以被攻击一次其中的一种服务,当你选择攻击某台服务 ...
- Flexible实现H5页面的rem布局适配
1.https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html (使用Flexible实现手淘H5页面的终端适配) 2.http ...
- Flask ajax 动态html 的javascript 事件失效
$('.db_edit').click(function(){ $(".editdbproduct").val($(this).parent().parent().find('.e ...
- cocos2dx lua 热加载实现
[Q]原创 2015-08-30 在公司使用cocos2dx+lua 开发游戏有一段时间了,刚好lua的热更新交给我负责.以前热更新的lua脚本大部分都是在下载之后加载.最近策划又有新需求,需要在游戏 ...
- 再看Scrapy(1) 基本概念
再看Scrapy(1) 基本概念 1 准备 安装scrapy: 国内镜像源(官方的pypi不稳定)安装 pip3 install -i https://pypi.douban.com/simple/ ...
- macOS 下 Visual Studio Code(VSCODE)安装配置及应用
Visual Studio Code 重新定义了 Code 编辑. 在任何操作系统上编辑和调试应用程序内置 Git 支持1000 种以上的扩展免费和开源 为什么使用VSCODE? 我们来看看以下功能: ...
- Android数据读取之Sqlite数据库操作
咱们书接上文,继续来说说Android数据读取,这回,我们要讲的是Sqlite数据库的相关操作.以一个实例开始吧: 首先,上图,看看做成后的效果: 大概描述:类似于浏览器的收藏夹,网站名称,网站地址, ...
- 【解题报告】2014ACM/ICPC上海赛区现场赛B
唉 谷歌出的神题,差点爆零了...三小时终于A掉 B题 题目大概是说从左上角的点出发,经过某路线最后回到原点,求每个格子被路线包含的圈数的平方和. 首先可以知道,对于某个格子来说,从该格子的任意一个 ...