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 的情况.单纯从技术角度来说,处理起来没什么难度,能想到的办法很多,但我觉得有一个很简单而且效率比较 ...
随机推荐
- Selenium with Python 008 - WebDriver 元素等待
如今大多数Web应用程序使用Ajax技术,当浏览器在加载页面时,页面上的元素可能并不是同时被加载完成的,这给元素的定位增加了困难.如果因为在加载某个元素时延迟而造成ElementNotVisibleE ...
- MailJobUtils 发送邮件
import java.util.List; import java.util.Properties; import javax.annotation.Resource; import javax.m ...
- 打造万能的Python开发环境
一.下载与安装 python的版本众多,主流的分2和3,还有各种小版本. django等也有众多版本. 在我们开发过程中,为使用不同的版本测试,在一台电脑上进行只能进行替换. 为了简化.我们使用con ...
- 【scala】异常处理
Scala 的异常处理和其它语言比如 Java 类似. 抛出异常 Scala 抛出异常的方法和 Java一样,使用 throw 方法 throw new IllegalArgumentExceptio ...
- Java 学习笔记(121208)
Java 修饰符 访问修饰符 修饰符 当前类 同一包内 子孙类 其他包 public Y Y Y Y protected Y Y Y N default Y Y N N private Y N N N ...
- Codeforces Round #394 (Div. 2) E. Dasha and Puzzle
E. Dasha and Puzzle time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...
- 一个css3 DNA 效果
这个效果就是 不断沿 Y 轴旋转 <div id="container"></div> <style> body{ background:bla ...
- c++指针初探
业余时间准备重温一下c++,因为在阅读Android源码到native层的时候感觉有点吃力,只是在大学时候很不用心的学过c++,所以重温下以便打好一些编程基础知识,本篇就很简单的对c++的指针做初步的 ...
- php语法笔记
1. php中设置页面的编码方式: header(“content-type:text/html;charset=utf-8”); 2. 数据类型 布尔类型:Boolean/bool:true.f ...
- 【解题报告】[动态规划]-PID69 / 过河卒
原题地址:http://www.rqnoj.cn/problem/69 解题思路: 用DP[i][j]表示到达(i,j)点的路径数,则 DP[0][0]=1 DP[i][j]=DP[i-1][j]+D ...