面对对象的三大特性:继承,多态,封装。

  函数和属性装到了一个非全局的命名空间----封装。

封装:

    在类中,静态属性,方法,对象属性都可以变成私有的,只需要在这些名字前加上‘__’(双下划线)。

    在类内,只要你的代码遇到‘__’(双下划线).名字,就会被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()

最新文章

  1. CPU的栈机制的一个小问题
  2. RFC3986编码 C 语言实现(支持大部分中文)
  3. C# ADO.NET SqlDataAdapter中传递参数
  4. IOS网络编程之请求内容
  5. 织梦内页读取栏目banner图
  6. [PHP] Eclipse开发PHP环境配置
  7. 使用WebClient上传文件时的一些问题
  8. async await的前世今生
  9. leetcode第12题--Integer to Roman
  10. 浅析DES与AES、RSA三种典型加密算法的比较
  11. SpriteKit游戏Delve随机生成地牢地图一个Bug的修复
  12. 五一之起一台服务器玩玩-centosl系统搭建lamp
  13. 【代码笔记】Web-CSS-CSS Display
  14. Math.abs(~2020) 按位取反后的绝对值是多少 2021, 按位取反后,比正数多1
  15. openfire连接数据库mysql
  16. 20155207 EXP7 网络欺诈技术防范
  17. Spring4.3整合Hibernate4.3搭建Spring MVC
  18. Dubbo学习笔记2:Dubbo服务提供端与消费端应用的搭建
  19. ZooKeeper(四)-- 第三方客户端 ZkClient的使用
  20. hdfs调优

热门文章

  1. Ajax技术基础
  2. ICE 中后台开发
  3. 使用MouseWithoutBordersSetup共享鼠标键盘教程
  4. iOS自动化探索(二)WDA API的使用
  5. [eShopOnContainers 学习系列] - 00 - 开发环境需求
  6. hibernate框架环境搭建与使用
  7. DRF 中 解决跨域 与 预检
  8. QGrapicsView类
  9. MySQL 解决 emoji表情 的方法,使用utf8mb4 字符集(4字节 UTF-8 Unicode 编码)
  10. Leetcode 1013. Partition Array Into Three Parts With Equal Sum