课上总结:
class T:
def __init__(self,x):
self.num = x
class F:
def __init__(self,x):
self.num = x
class P:
def __init__(self,a,b):
self.t = T(a)
self.f = F(b)
print('水池里共有%d龟%d鱼'%(self.t.num,self.f.num))
这里将第三类中x,y改成a,b方便对比,对应T,F中的就该是a,b,这和上节课自己总结的一样结构为
self.变量 (属性的意思)= 类(形参)。
这里说一下这个形参,比如我想要1只龟10鱼,那么要输出的条件就是类T,F中的x为1,10,现在定义了P,来直接说明这个池子的两类,所以在P中直接将TF实例化,此时他们的形参就该和P同步,因为最后输入的时候是输入
pool = P (1,10)
整体逻辑就是,通过P输入数据,然后对应里面有两个另外类的实例化,并输入对应的数据,此时若要调用里面的函数就可以pool.(对应类的变量).(该类里面的函数)
需要注意的是,类.函数是不行都,类都需要一个对象,然后对象.函数
2.就是小甲鱼说的类,类对象,实例对象:
self(实例对象).属性 = 类
首先类对象相当于类下面定义的属性,它不会因为实例对象属性的变化而变化。若类对象即C.count变化,其属性变化,则abc实例都会跟着变化。
但是若实例化对象给自己属性赋值,这时候就不会再听命与大类的属性,而是将自己属性进行覆盖
若属性名和方法名重合,则属性会覆盖方法,因此定义名字和方法的时候尽量避免重复(属性:名词。方法:动词)
>>> class C:
def x(self):
print("Xman")
>>> c = C()
>>> c.x()
Xman
>>> c.x = 111 # 定义x属性
>>> c.x
111
>>> c.x() # 方法已经被覆盖掉了,所以调用报错了
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
c.x()
TypeError: 'int' object is not callable
3.若将类实例化一个对象后,对对象进行赋值。然后删除类,此时实例化对象仍然可以用类的方法,因为已经存储在内存中
课后作业:
1.什么时候用组合,什么时候用继承?
答:根据实际应用场景确定。简单的说,组合用于“有一个”场景中,继承用于“是一个”场景中。例如,水池里有一个乌龟,天上有一只鸟,地上有一个小甲鱼,这些适合使用组合。丝瓜是瓜,女人是人,鲨鱼是鱼,这些就应该使用继承。
4.请问以下类定义中哪些是类属性,哪些是实例属性?
class C:
num = 0
def __init__(self):
self.x = 4
self.y = 5
C.count = 6
答:num和count是类属性(静态变量),x和y是实例属性。大多数情况下,你应该考虑使用实例属性,而不是类属性(类属性通常仅用来跟踪与类相关的值)。
0.思考这一讲学习的内容,请动手在一个类中定义一个变量,用于跟踪类有多少个实例被创建(当实例化一个对象,这个变量+1,当销毁一个对象,这个变量自动-1)。
class A():
n = 0
def __init__(self):
A.n += 1
def __del__(self):
A.n -= 1
a = A()
b = A()
c = A()
del a
print(A.n)
del的作用是在删除之前执行操作
类下面定义一个属性,然后用init,每次实例化时就会初始化一次,因此每次类属性都会改变。注意这里是A.n,而不是self.n,因为self只针对实例化对象,并不会叠加,A的话,每次输入一个,A就会增加,而且A不会变
1.定义一个栈(Stack)类,用于模拟一种具有后进先出(LIFO)特征的数据结构。至少需要有以下办法:
方法名 含义
isEmpty() 判断当前栈是否为空(返回True或False)
push() 往栈的顶部压入一个数据项
pop() 从栈顶弹出一个数据项(并在栈中删除)
top() 显示当前栈顶的一个数据项
botton() 显示当前栈底的一个数据项
class Stack():
A = []
def isEmpyt(self):
if Stack.A == []:
print('True')
else:
print('栈内有数据')
def push(self):
n = 1
while n != 'y':
print('请输入一个数:',end='')
Stack.A.append(int(input()))
print('现在栈为:',Stack.A)
n = input('任意键继续,y结束输入:')
def pop(self):
m =input('确认弹出一个栈顶数据项?y确定,任意键退出')
while m == 'y':
name = Stack.A.pop(0)
print('您弹出了数据%d'%name)
print('现在栈为:',Stack.A)
m = input('继续弹出请按y否则任意键:')
def top(self):
if Stack.A == []:
print('抱歉,栈为空')
else:
print('栈顶的数据为:%s'%Stack.A[0])
def botton(self):
if Stack.A == []:
print('抱歉,栈为空')
else:
num = int(len(Stack.A)) - 1
print('栈底数据为:%s'%Stack.A[num])
a = Stack()
别人方法的借鉴
def __init__(self, start=[]):
self.stack = []
for x in start:
self.push(x)
def push(self, obj): # 入栈
print("成功入栈数据:", obj)
self.stack.append(obj)
第一段学习到的是定义一个形参,然后如果形参不是空,是由数据的,则在输入栈之前会把形参数据先一步输入
第二段学习到的是利用形参完成input的功能