面向对象初始
面向对象
-
-
类
-
-
-
-
概念:具有相同属性和技能的一个事物。
-
面向对象的好处:
- 使得代码之间的角色关系更加清晰
- 增强了代码的可拓展性。
- 约束了对象的属性和功能。
-
-
-
-
- 面向对象的特点:
- 结局的不确定性。
- 不关注程序过程的执行。只关注程序中的对象以及对象之间的关系
- 类名
- 引用静态变量
- 查看静态变量的方式:
- A.__dict__["静态变量”]:只能查看,不能修改、删除。
- A.静态变量:可以查看、修改、删除。
- 查看静态变量的方式:
- 引用动态变量(方法、动态属性:默认带一个self的参数,)
-
- 类名+方法名 查看这个方法的内存地址。
- 类名+方法名(实参),调用了这个方法,必须传一个参数给self。
-
- 引用静态变量
- 类名+():相当于创建了一个实例,等同于创建了一个对象。即对象or实例 = 类名+()
- 实例化过程:
- 创建了一个实例,将会作为一个实参。
- 自动触发了__init__函数,并将实例作为一个实参传给了self。
- 执行完__init__函数后,将self自动返回给调用者。
- __init__: 是一个初始化方法,是给一个对象添加基础属性的方法,一般用于self赋值。
- 面向对象的特点:
-
-
-
对象
-
概念:对一个类的具体描述
-
在类的内部,self就是类的对象
-
在类的外部,每个对象都对应着一个名称,这个对象指向对象的内存空间。
-
-
-
- 属性的调用
- 对象名.属性 (点调用法)
- 对象名.__dict__[属性名]
- 方法的调用
- 类名+方法名+(对象名):方法中的self指向对象本身
- 对象名.方法名+():方法中的self直接指向这个对象。
-
类命名空间与对象的命名空间
-
创建一个类就会创建一个类的命名空间,用来储存类的属性以及所含有的方法。属性包括静态属性以及动态属性(方法)。
-
-
其中类的属性是可以共享给所有对象的。
-
方法是绑定到具体的对象的。对象通过自己内存空间的类对象指针找到类的方法。
-
-
-
-
-
- 对象的内存空间只存储对象的特有属性,不存储类的静态属性以及方法。
- 方法和静态属性存储在类的内存空间中,为了节省内存,让多个对象共享类的属性以及方法
- 对象使用名字调用属性,先从自己的内存空间查找,然后再从所属类的内存空间查找。
- 对于静态属性的修改,使用类名类调用属性来修改。
-
-
-
组合
-
定义:一个类的对象作为一个类对象的属性。大白话就是什么有什么。
-
作用:有些对象没发独立发挥它的作用,所以必须依赖其他对象,所以用到了组合。
-
-
-
-
交互
-
定义:将一个对象作为一个参数传递给类的方法。
-
-
面向对象的三大特性
-
-
继承
-
父类:基类、超类; 子类:派生类
-
类型
-
单继承
- __bases__为内置属性,可以查看一个类的父类
- python中所以类的父类默认继承object,继承了object类的都叫新式类。
- 如果一个类中没有继承f父类,就默认继承了object类。
-
多继承
-
-
-

-
-
封装
-
定义:函数和属性装到了一个非非全局的命名空间称为封装。
-
作用:隐藏对象的属性和实现细节,仅对外提供公共访问方式。
- 原则:
- 将不需要对外提供的内容都隐藏起来;
- 把属性都隐藏,提供公共方法对其访问。
- 私有属性以及私有方法
- 私有属性
- 定义一个私有名字就是在私有名字前面加两天下划线“__”,所谓私有,就是不能在类的外面去引用他。
- 一个私有名字在存储过程中,仍然会出现在A.__dict__中。
- python对名字进行了修改:_类名__名字。在类的外部调用,必须得用_类名__方法名调用。而在内部可以正常调用:类名.__名字。
- 这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。
- 私有属性
-
-
1 class A: 2 __N = 'aaa' # 静态变量 3 def func(self): 4 print(A.__N) # 在类的内部使用正常 5 print(A._A__N) ##类中所有的双下划线都会自动变形为:_类名__x的形式
6 7 a = A() 8 a.func() 9 print(A.__N) # 在类的外部直接使用 报错
-
-
-
- 私有方法
-
-
1 class C: 2 def __wahaha(self): ##方法也可以私有化,只需要给方面名前面加上两下划线就ok 3 print('wahaha') 4 def ADCa(self): 5 self.__wahaha() 6 c = C() 7 c.ADCa()
-
-
- 在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。
-
1 class D: 2 def __func(self): # '_D__func' 3 print('in func') 4 5 class E(D): 6 def __init__(self): 7 self.__func() # '_E__func' 8 e = E()
报错
1 class D: 2 def __init__(self): 3 self.__func() ###在D中调用_D__func() ,所以输出 'in D' 4 def __func(self): 5 print('in D') 6 7 class E(D): 8 def __func(self): 9 print('in E') 10 e = E() ##实例化E,子类没有__init__方法,自动触发父类的__init__方法
1 class F: 2 pass 3 F.__name = 'alex' # 不是在创建私有属性,变形只在类的内部发生 4 print(F.__name) 5 print(F.__dict__)
输出结果:
alex
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'F' objects>, '__weakref__': <attribute '__weakref__' of 'F' objects>, '__doc__': None, '__name': 'alex'}
-
-
-
-
- 与java的对比
- 公有的public:在类的内部可以使用,子类可以使用,外部可以使用。python中所有正常的名字;
- 保护的protect:在类的内部可以使用,子类可以使用,外部可以使用,python中没有
- 私有的private:只有在类的内部可以使用,外部以及子类不可使用。python中的双下划线“__”名字。
- 与java的对比
-
- 私有的用法
-
- 当一个方法不想被子类继承的时候;
- 有些属性或者方法不希望外部调用,只想提供给内部方法调用的时候。
-
-
-
-
-
property
-
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值。用来将一个方法伪装成一个属性。
-
作用:
-
@property 可以将一个方法伪装成为一个属性。
-
从原来的的对象名+'.'+方法名+()变为 对象名+'.'+方法。
-
-
-
1 class Person: 2 def __init__(self,name,weight,height): 3 self.name = name 4 self.__height = height 5 self.__weight = weight 6 @property 7 def bmi(self): 8 return self.__weight / self.__height ** 2 9 print(Person.__dict__) 10 p = Person('大表哥',92,1.85) 11 print(p.__dict__) 12 print(p.bmi) # 对这个属性 只能看了
-
-
-
- 被property装饰的方法仍然是个方法,存在类的dict中;
- 对象的__dict__不会储存这个伪属性。
- 在一个类的加载过程中,会先加载这个类中的名字,包括被property装饰的名字,在实例化对象的时候,python解释器会到类的空间里看看有没有被这装饰的属性,如果有的话,实例化的时候就不能在自己的对象空间里创建这个属性了。
- 修改被@property修饰的属性
-
-
1 class Person: 2 def __init__(self,n): 3 self.__name = n # 私有的属性了 4 @property 5 def name(self): 6 return self.__name 7 8 @name.setter # 重要程度 *** 9 def name(self,new_name): 10 if type(new_name) is str: 11 self.__name = new_name 12 else: 13 print('您提供的姓名数据类型不合法') 14 15 p = Person('alex') 16 print(p.name) #def name(self): 17 p.name = 'sb' #def name(self,new_name): #调用了被time.setter装饰的函数,然后将sb赋值给new_name,对私有属性 name 进行修改。 18 print(p.name) #def name(self): 19 p.name = 123 #def name(self,new_name): 20 print(p.name) #def name(self):

-
-
- 删除被@property装饰的属性
-
1 class Person: 2 def __init__(self,n): 3 self.__name = n # 私有的属性 4 @property 5 def name(self): 6 return self.__name 7 # @name.deleter 8 # def name(self): 9 # print('name 被删除了') 10 @name.deleter # 重要程度* 11 def name(self): 12 del self.__name 13 14 p = Person('alex') 15 print(p.name) 16 del p.name # 只是执行了被@name.deleter装饰的函数 ####del p.name 会执行被@name.deleter修饰的函数 17 print(p.name)
-
-
- 总结:
@property --> func 将方法伪装成属性,只管看的事儿;
@func.setter --> func 对伪装的属性进行赋值的时候调用这个方法 一般情况下用来做修改
@func.deleter --> func 在执行del 对象.func的时候调用这个方法 一般情况下用来做删除 基本不用;
- 总结:
-
将一些需要随着一部分属性的变化而变化的值的计算过程 从方法 伪装成属性
将私有的属性保护起来,让修改的部分增加一些约束,来提高程序的稳定性和数据的安全性
-
classmethod
-
类方法,可以直接被类调用,不需要默认传参数,只需要传一个类参数就行了。不依赖对象的方法,就应该定义为类方法,可以任意操作类中的静态变量。
- 由于不是用对象内存空间中的属性,所以不会将对象和方法绑在一起,而是将类和方法绑定到一起。对象依然可以通过类对象指针找到与类绑定的类方法。
1 class Goods: 2 __discount = 0.8 3 def __init__(self,name,ori_price,): 4 self.name = name 5 self.__ori_price = ori_price 6 @property 7 def price(self): 8 return self.__ori_price*Goods.__discount 9 @classmethod 10 def change_discount(cls,new_discount): 11 cls.__discount = new_discount 12 13 14 Goods.change_dicount(0.5) ###不依赖对象的方法,直接用类方法对类的静态属性进行修改。 15 apple = Goods("Apple",10) 16 mango = Goods("Mango",20) 17 print(apple.price) 18 print(mango.price)
-
-
staticmethod
-
定义:静态方法没有默认参数,当成普通的函数使用即可。
-
不是绑定方法,没有和任何对象或者类发生任何的绑定。
-
-
-
-
使用什么样的方法要看具体用到了哪些名称空间中的变量
当一个方法要使用对象的属性时 就是用普通的方法
当一个方法要使用类中的静态属性时 就是用类方法
当一个方法要既不使用对象的属性也不使用类中的静态属性时,就可以使用staticmethod静态方法
-
浙公网安备 33010602011771号