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 的情况.单纯从技术角度来说,处理起来没什么难度,能想到的办法很多,但我觉得有一个很简单而且效率比较 ...
随机推荐
- TCP和Http的区别!(转) 真心有帮助!!!
一.From:http://thisliy.javaeye.com/blog/710122 http://wenku.baidu.com/view/14a30d0102020740be1e9b84.h ...
- 016——VUE中v-show的使用与v-if的差异对比
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- SpringBoot_10_打成jar包后使用外部配置文件中的配置来启动工程
一.前言 三.参考资料 1.Spring Boot配置文件放在jar外部
- 登录页面jsp跳转到另一个jsp 与jsp-Servlet-jsp
登录页面jsp 到另一个jsp,与jsp-Servlet-jsp 都是可以从表单提交参数信息. 但是jsp-jsp ,只能通过<%=request.getParameter("use ...
- Kotlin 第二弹:Android 中 PDF 创建与渲染实践
这是 Kotlin 练习的的第二篇.这一篇的由来是因为刚刚在 Android 开发者官网查看 API 的时候,偶然看到了角落里面的 pdf 相关. 我仔细看看了详细文档,发现这个还蛮有意思的,关键是编 ...
- Android内存优化(一)DVM和ART原理初探
相关文章 Android内存优化系列 Java虚拟机系列 前言 要学习Android的内存优化,首先要了解Java虚拟机,此前我用了多篇文章来介绍Java虚拟机的知识,就是为了这个系列做铺垫.在And ...
- mysql-jdbc创建Statement与执行SQL
使用JDBC创建Connection后,执行SQL需要先创建Statement Statement stmt = connection.createStatement(); 创建代码如下 public ...
- HDU - 6201:transaction transaction transaction(最长路)
Kelukin is a businessman. Every day, he travels around cities to do some business. On August 17th, i ...
- datetimebox
$.extend($.fn.datagrid.defaults.editors, { datetimebox: {// datetimebox就是你要自定义editor的名称 init: functi ...
- Visual Studio Code如何调试代码
首先安装扩展调试插件debugger for chrome 点击瓢虫按钮,进行调试项目的配置,点击配置按钮 选择Chrome环境, 会弹出Chrome调试配置文件launch.json,修改下端口即可 ...