补充一些小知识点: for 变量 in 变量: else: 语句 使用的时候是会for循环结束之后,就会执行else语句;除非是有break直接将for循环结束了
进行比大小的时候,比较的都是数据的key。
面向对象的一些小定义
- 面向对象:对象具有方法,一般自身带有方法函数即可。不同对象调用不同方法,不会互相调用
- 面向过程:互相调用
- 类:一个类定义了每个对象共有的属性和方法,用来描述具有相同属性和方法的对象的集合 对象是类的实例 使用前要实例化,
类是用来创建对象的,所以对象具有类的属性和方法。先有类,再有对象。
;面向对象开发前,应该先分析需求,确定一下,再看包含了那些类。再由类中确定属性和方法。类就是很多物品都具有的相似点的归纳,需要对相似点进行整理归纳,
—>名词提炼法 分析 整个业务流程,出现的 名词,通常就是找到的类类名必须是驼峰命名法
类三要素
:类名、属性、对象[]- 对象:s
- 方法:类中的函数
- 类变量:再实例化对象中是共用的,就算定义变量,但是不会再类中的方法李,类变量一般不会作为实例变量使用
- 数据成员:进行操作的相关数据
- 方法重写:子类继承父类的方法,但所不满足需求,可进行重写,也就算重载,覆盖。
- **局部变量:**方法的变量,只作用于当前实例的类
- 继承:一个派生类继承基类
- 实例化:类进行调用,需要实例化,那就算对象。
- 对象:通过类定义的数据结构实例,对象包括两个数据成员,类变量、实例变量。和方法。类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
类与对象的关系
:不同对象中直接属性可能会不同,是因为对象可以继承或者多态,这样就可以新增
class ClassName:
statement..
类的调用
属性调用
:类名.方法
实例化调用
:实例化名字.方法
- 值得注意的是 直接类名进行调用的时候,若存在self实例化参数,一定要给予,否则会出错。
class Myclass:
i = 12345
def d(self):
return "hello world"
x = Myclass() # 实例化
print(x.i,x.d()) #12345 hello world 实例化调用
print(Myclass.i)#12345 属性应用
print(Myclass.d(1))#这个时候 self必须给参数 实例化则不用
- 在类中有一个
__init__()
方法,类的实例化操作会自动调用__init__()方法,可以使用@staticmethod @classmethod
进行避免,在后面的内置函数文章里面有写,还没发出来,跳过去看即可。一旦类被实例化,最先执行的一定是init方法。
class initClass:
i = 888
def __init__(self,x):
print("this is init")
self.x = x
@staticmethod #这个时候就会报错 因为没有x的参数进来 说明这个时候 没有初始化
def test(self):
print("this is test")
print(self.x) #7
print(x) #<__main__.Myclass object at 0x7efd34805b00>
@staticmethod # 可以不进行初始化 就进行调用,但是如果有实例化操作self 就会报错。
def t(): # 注意这里有self参数的话 就要注意给予参数了 不给不行
print('1111')
# 不初始化调用
#initClass.test(7)# 这个时候就会报错 因为没有x的参数进来 说明这个时候 没有初始化
initClass.t()
print('init 初始化')
i = initClass(7)
i.test() # 如果加上 staticmethod 就算静态方法 给予参数 但是会报错。没有基于static 就算类方法,会直接调用 忽略self
# 会县输出 初始化
self参数
self 代表类的实例,而非类
,定义的是第一个参数
而非self的名字,所以是别的名字也没有关系,通常是self。self.__class__ 定义的是指向类的名称
,self 不是python的关键字
# self 代表类的实例,而非类 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
# self只是名字,一般第一个参数,就作为类的实例,代表当前对象的地址, self.__class_ 则指向类的名称。
# self 换成别的名字也一样
class tt :
def ttfun(self):
print(self) #<__main__.tt object at 0x7fb56f44db38> 对象地址
print(self.__class__) # 指向类 说出类的名字
t1 = tt()
t1.ttfun()
class tt1 :
def tt1fun(self1):
print(self1) #<__main__.tt1 object at 0x7f0e6a2494a8>
print(self1.__class__) # 指向类 说出类的名字 <class '__main__.tt1'>
t11 = tt1()
t11.tt1fun()
类的 方法
- 使用
def
进行定义,类方法必须包含参数self,并且为第一个参数,self可以是别的名称,但是必须是第一个,第一个参数表示类的实例。
- 如果不定义参数,是不行的,会报错
TypeError: t() takes 0 positional arguments but 1 was given
,必须要给一个参数 __变量名
为私有变量,在类中被定义,外部无法直接访问- self为类的实例,而非类,所以可以直接在类的内部调用这些方法。
class people:
name=""
age= 0
__weight =0 # 私有属性 外部无法直接访问
# 构造函数
def __init__(self,n,a,w):
#TypeError: object() takes no parameters init的横线写错了 漏了
self.name=n
self.age = a
self.__weight= w
print(self.name, self.age, self.__weight,'init') #one two three init
self.speak() # 可以调用 self是实例
def speak(self):
print(self.name,self.age,self.__weight)
p = people('one','two','three')
p.speak()#one two three
print(p.name)#one
print(p.age)#two
#print(p.__weight) no attribute
# print(p.weight) no attribute
继承
- 继承定义 ,派生类的参数就是父类,
通过父类名作为参数,来进行继承
,以及基类名必须与派生类定义在一个作用域内
,就是不能跨着调?
class DerivedClassName(BaseClassName1):
<statement-1>
.
<statement-N>
- 基类定义在另一个模块中
class DerivedClassName(modname.BaseClassName
- 例子:
继承后调用父类,传递的参数是派生类的实例,所以后期调用的函数,也是调用派生类的。类中的函数会被重载,但是不影响基类原本的函数,可以理解为复制、重新构造一个
- 注意
self指向
class people:
name=""
age= 0
__weight =0 # 私有属性 外部无法直接访问
# 构造函数
def __init__(self,n,a,w):
#TypeError: object() takes no parameters init的横线写错了 漏了
self.name=n
self.age = a
self.__weight= w
print(self.name, self.age, self.__weight,'init') #one two three init
print(self.__class__)#student
self.speak()
def speak(self):
print(self.name,self.age,self.__weight)
p = people('one','two','three')
# 继承上面的people类
class student(people):
grade = ""
def __init__(self,q,w,e,r):
#调用父类的构造
people.__init__(self,q,w,e) # 此时的self是student的实例,所以传递过去 就变了 会调用
self.grade = r
def speak(self):
print(self.__class__)# student
print('this is student speak')
s = student('ye',10,60,3)
p.speak()# onetwothree
多继承
- 多个父类作为参数,但是注意如果存在相同方法名,子类使用时候没有指定,从左到右进行搜索方法。
注意self指向就好
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
<statement-N>
# 类定义
class people:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class student(people):
grade = ''
def __init__(self, n, a, w, g):
# 调用父类的构函
people.__init__(self, n, a, w)
self.grade = g
# 覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
# 另一个类,多重继承之前的准备
class speaker():
topic = ''
name = ''
def __init__(self, n, t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s" % (self.name, self.topic))
# 多重继承
class sample(speaker, student):
a = ''
def __init__(self, n, a, w, g, t):
student.__init__(self, n, a, w, g)
speaker.__init__(self, n, t)
test = sample("Tim", 25, 80, 4, "Python")
test.speak() # 方法名同,默认调用的是在括号中排前地父类的方法 我叫 Tim,我是一个演说家,我演讲的主题是 Pytho
#注意self 指向就好了
方法重写/重载
- 即子类重新定义方法,但是父类的函数并不会影响,可以
使用super用子类对象调用父类已被覆盖的方法,也就是被使用的父类方法
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
c = Child() # 子类实例
c