(小甲鱼python)类和对象(III)总结 类的绑定,self,__dict__的妙用

一、基础复习

1.类和对象(I)总结 类的定义、self的用法
2.类的继承、类的判断isinstance()、issubclass()、多重继承、类的组合

二、类的绑定

1.类的绑定(self的妙用)
例1:

>>> class Cat:
	def say(self):
		print("喵喵喵")

		
>>> class Dog:
	def say(self):
		print("啊呦,,,,")

		
>>> class Turtle:
	def say(self):
		print("不积跬步无以至千里。")

		
>>> class Garden:
	t=Turtle()
	c=Cat()
	d=Dog()
	def say(self):
		self.t.say()
		self.c.say()
		self.d.say()

		
>>> g=Garden()
>>> g.say()
不积跬步无以至千里。
喵喵喵
啊呦,,,,
>>> 

这里需要用到self.t.say(),而不是t.say(),t.say()会报错

>>> class Garden:
	t=Turtle()
	c=Cat()
	d=Dog()
	def say(self):
		t.say()         #会报错
		c.say()
		d.say()

		
>>> g=Garden()
>>> g.say()
Traceback (most recent call last):
  File "", line 1, in 
    g.say()
  File "", line 6, in say
    t.say()
NameError: name 't' is not defined

例2:
c中定义的元素d中没有定义,所以会报错。

>>> d=C()
>>> d.x=234
>>> c.x
>>> d=C()
>>> d.x=234
>>> c.x
Traceback (most recent call last):
  File "", line 1, in 
    c.x
AttributeError: 'C' object has no attribute 'x'

2.查看属性__dict__
dict左右有两个下划线
例3:

>>> c.__dict__
{'x': 520}
>>> d.__dict__
{'x': 234}
>>> d.y=660
>>> d.__dict__
{'x': 234, 'y': 660}

例4:

>>> class C:
	def set_x(self,v):
		self.x=v

		
>>> c=C()
>>> c.__dict__
{}
>>> c.set_x(250)
>>> c.__dict__
{'x': 250}
>>> c.x
250

3.最简单类元素定义
例5:
定义一个空的类,然后对类进行属性的赋值。

>>> class C:
	pass

>>> C.x=250
>>> C.y="小甲鱼"
>>> C.z=[1,2,3]
>>> print(C.x)
250
>>> 
>>> print(C.y)
小甲鱼
>>> 
>>> print(C.z)
[1, 2, 3]

例6:

>>> d={}
>>> d['x']=250
>>> d['y']="小甲鱼"
>>> d['z']=[1,2,3]
>>> print(d['x'])
250
>>> print(d['y'])
小甲鱼
>>> print(d['z'])
[1, 2, 3]
>>> 
>>> 
>>> class C:
	pass

>>> c=C()
>>> c.x=250
>>> c.y="小甲鱼"
>>> c.z=[1,2,3]

课后题:
1.请问方法绑定的意义是什么?
答:共享!
解析:一辆共享单车,如何识别是谁在骑它?无非就是通过扫码绑定
一样的道理,为了节约内存,Python 没必要为每一个对象的方法都做一次拷贝,但如何区分是谁在调用?
通过 self 参数的绑定来识别嘛
2. 下面代码中,调用 c.hello() 和 C.hello© 的结果是一样的,请问它们是完全等价的吗?

>>> class C:
...     def hello(self):
...         print("Hello FishC.")
...
>>> c = C()
>>> c.hello()
Hello FishC.
>>> C.hello(c)
Hello FishC.

答:是的。
解析:
是的!方法相比函数来说,确实就是多了这么一个绑定的操作。因此,C.hello© 属于函数调用,而 c.hello() 则属于方法调用。
3.请问下面代码会打印什么呢?

>>> class C:
...     x = 100
...     def get_x(self):
...         print(x)
...
>>> c = C()
>>> c.x = 250
>>> c.get_x()
>>> # 请问这里会打印什么内容?

答:会报错(抛出异常 NameError: name ‘x’ is not defined)。
解析:在类的方法中直接访问 x 属性,并不会去对象或者类中找 x,根据 LEGB 原则,去找对应的变量。
理解了下面代码,大家应该就很清晰了:

>>> x = 123
>>> class C:
...     x = 100
...     def get_x(self):
...         print(f"x = {x}")
...         print(f"self.x = {self.x}")
...
>>> c = C()
>>> c.get_x()
x = 123
self.x = 100
>>> c.x = 250
>>> c.get_x()
x = 123
self.x = 250

4.请问下面代码会打印什么呢?

>>> class C:
...     x = 100
...     def get_x(self):
...         print(self.x)
...
>>> c = C()
>>> c.x = 250
>>> c.get_x()
>>> # 请问这里会打印什么内容?

答:250
解析:这里 c.x = 250,设置的是对象的 x 属性,当对象设置了属性之后,就不会再去访问其类的同名属性了。
5.请问下面代码会打印什么呢?

>>> class C:
...     x = 100
...     def get_x(self):
...         print(C.x)
...
>>> c = C()
>>> c.x = 250
>>> c.get_x()
>>> # 请问这里会打印什么内容?

答:100
解析:虽然 c.x = 250 设置的是对象的 x 属性,但是这里的细节是 print(C.x),所以打印的永远是类的 x 属性(而非对象的)。
6. 请问下面代码会打印什么呢?

>>> class C:
...     def f(self):
...         print("Hello FishC.")
...
>>> c = C()
>>> type(C.f) == type(c.f)
>>> # 请问这里会打印什么内容?

答:False。
解析:因为一个是函数(在类中定义,它还是一个函数),一个是方法(绑定了对象,那么它就是一个方法)。

>>> type(C.f)

>>> type(c.f)

7.请问下面代码会打印什么呢?

>>> class C:
...     x = []
...     def add_x(self, x):
...         self.x.append(x)
...
>>> c = C()
>>> d = C()
>>> c.add_x(250)
>>> d.add_x(520)
>>> c.x
>>> # 请问这里会打印什么内容?

答:[250, 520]
解析:
列表这类容器啊,就是这样的。它是单独存储的,然后所有它的引用都是指向相同的位置。

你可能感兴趣的:(小甲鱼课程笔记,python,python,数学建模,开发语言)