python 面向对象

参考 https://www.cnblogs.com/happyframework/p/3255962.html

面向对象

先上一张图

几个规则:

  1. 一切都是对象,python中一切都是对象,每个对象都包含一个__class__属性以标记其所属类型。
  2. 每个对象(记得一切都是对象啊)都包含一个__dict__属性以存储所有属性和方法。
  3. 每个类型都包含一个__bases__属性以标记其父类。
  4. 属性和方法的访问规则:依次搜索instance、子类、父类、父类的父类、直到object的__dict__,如果找到就返回。
  5. 属性和方法的设置规则:直接设置instance.__dict__。
  6. 以上属性和方法访问或设置规则没有考虑“魔法方法”,下文会解释。

 示例

 1 # coding=utf-8
 2 
 3 __metaclass__ = type
 4 
 5 # 类型定义
 6 # 实例方法必的第一个参数代表类型实例,类似其他语言的this。
 7 class Animal:
 8     name = "未知" # 属性定义。
 9 
10     def __init__(self, name): #构造方法定义。
11         self.name = name
12 
13     def getName(self): # 实例方法定义。
14         return self.name
15 
16     def setName(self, value):
17         self.name = value
18 
19 print(Animal.name) # 未知
20 print(Animal.__dict__["name"]) # 未知
21 
22 animal = Animal("狗狗")
23 print(animal.name) # 狗狗
24 print(animal.__dict__["name"]) # 狗狗
25 print(Animal.name) # 未知
26 print(Animal.__dict__["name"]) # 未知
27 print(animal.__class__.name) # 未知
28 print(animal.__class__.__dict__["name"]) # 未知
1 # 类型定义中的代码会执行,是一个独立的作用域。
2 class TestClass:
3     print("类型定义中") #类型定义中

绑定方法和未绑定方法

 1 class TestClass:
 2     def method(self):
 3         print("测试方法")
 4 
 5 test = TestClass()
 6 print(TestClass.method) #<unbound method TestClass.method>
 7 print(test.method) #<bound method TestClass.method of <__main__.TestClass object at 0x021B46D0>>
 8 
 9 TestClass.method(test) #测试方法
10 test.method() #测试方法
绑定方法已经绑定了对象示例,调用的时刻不用也不能传入self参数了。

注:使用对象访问实例方法为何会返回绑定方法?这个还得等到学完“魔法方法”才能解释,内部其实是拦截对方法成员的访问,返回了一个Callable对象。

私有成员

1 # 私有成员
2 class TestClass:
3     __private_property = 1
4 
5     def __private_method():
6         pass
7 
8 print(TestClass.__dict__) # {'__module__': '__main__', '_TestClass__private_method': <function __private_method at 0x0212B970>, '_TestClass__private_property': 1
难怪访问不了了,名称已经被修改了,增加了访问的难度而已。

多重继承

 1 #多重继承
 2 class Base1:
 3     pass
 4 
 5 class Base2:
 6     pass
 7 
 8 class Child(Base2, Base1):
 9     pass
10 
11 child = Child()
12 print(isinstance(child, Child)) # True
13 print(isinstance(child, Base2)) # True
14 print(isinstance(child, Base1)) # True
如果继承的多个类型之间有重名的成员,左侧的基类优先级要高,上例子Base2会胜出。

接口那里去了,鸭子类型比接口更好用。

 1 class TestClass1:
 2     def say(self):
 3         print("我是鸭子1")
 4 
 5 class TestClass2:
 6     def say(self):
 7         print("我是鸭子2")
 8 
 9 def duck_say(duck):
10     duck.say()
11 
12 duck_say(TestClass1()) # 我是鸭子1
13 duck_say(TestClass2()) # 我是鸭子2
调用父类
 1 # 调用父类
 2 class Base:
 3     def say(self):
 4         print("Base")
 5 
 6 class Child(Base):
 7     def say(self):
 8         Base.say(self)
 9         super(Child, self).say()
10         print("Child")
11 
12 child = Child()
13 child.say()
posted @ 2021-04-21 02:41  伐丶木累  阅读(58)  评论(0编辑  收藏  举报