一些术语
- 类(class):
- 用来描述具有相同的属性和方法的对象的集合。
- 它定义了该集合中每个对象所共有的属性和方法。
- 对象是类的实例。
""" an example 4 learning""" class nClass: i = 123456#<statement-1>可以有许多个<statement-i> 并且可以在外部访问 def f(self): return('helllllo') x = nClass() #实例化 print("属性i为:",x.i) print("f的输出为:",x.f())
- 类变量:
- 类变量在整个实例化的对象中是公用的。
- 类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用
- 方法:类中定义的函数
- 方法重写:
- 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,
- 这个过程叫方法的覆盖(override),也称为方法的重写。
- 局部变量:定义在函数(方法)中的变量,是作用于当前实例的类
- 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量
- 继承(可以部分参考C++):
- 即一个派生类(derived class)继承基类(base class)的字段和方法。
- 继承也允许把一个派生类的对象作为一个基类对象对待。
- 例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:
- 通过类定义的数据结构实例。
- 对象包括两个数据成员(类变量和实例变量)和方法。
类的定义
""" an example 4 learning"""
class nClass:
i = 123456#<statement-1>可以有许多个<statement-i> 并且可以在外部访问
def f(self):
return('helllllo')
x = nClass() #实例化
print("属性i为:",x.i)
print("f的输出为:",x.f())
class Stu():#类
pass
stu_1 = Stu() #这里将stu_1用Stu实例化,叫实例化
创建实例是通过 对象名 = 类名() 实现
__init__方法:用来强制给一个类绑定属性,参数通过__init__穿戴到实例化操作上
class Stu(object):
def __init__(self,name,score):
self.name = name
self.score = score
stu_1 = Stu(zhangsan,99)
print(stu_1.name,stu_1.score)
__init__的第一个参数必须是self(这个类本身,习惯写作self)
可以用self在内部绑定属性
self不用传入,Python自己传
self.name是属性变量 name是外界变量(传入)
self代表类的实例,而非类,也就是对象
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的*第一个参数名称* 按照惯例它的名称是 self。
在类的方法中 继承 self
可以方便在方法中访问类内部变量
和类内部方法
class Test:
def prt(self):
print(self)
print(self.__class__)
结果为:
<main.Test instance at 0x100771878>
main.Test
这个self换成别的名字也是一样的,self代表的是当前对象(实例)的地址?->print(self)可见
self可以不写吗?
如例子:
class Test:
def ppr():
print(self)
t = Test()
t.ppr()
运行结果
Traceback (most recent call last):
File "cl.py", line 6, in <module>
t.ppr()
TypeError: ppr() takes 0 positional arguments but 1 was given
实际运行中将 t.ppr()解释成了 Test.ppr(t) 所以报错多一个参数
所以这里的ppr()应该写一个self才可以 ->ppr(self)
当然在定义中不使用这个类本身时不需要传入self,就不用写self
这样的称为类方法
类的方法
#类定义
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))
#实例化
p = people('lily',10,30)
p.speak()
继承
支持继承
定义如下:
class DrivedClassName(BaseClassName):
#子类,派生类 #父类,基类
#子类继承父类的属性和方法
#并且在自身内部可以添加属性和方法
<statement-1>
.
.
.
<statement-N>
#基类和派生类需要在一个作用域内
example:
#类定义
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
#reride(覆写)父类方法
def speak():
print("%s says: I'm %d years old,I'm in %d grade"%(self.name,self.age,self.grade))
#实例化
s = student('lily',10,4)
s.speak()
self用法在继承中
class Parent:
def pprt(self):
print(self)
class Child(Parent):
def cprt(self):
print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()
结果:
<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>
运行c.cprt()时指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt©,所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找到父类Parent中定义了pprt()方法,所以就会成功调用,这里的self指的仍是Child类的内容。
多继承
类定义:
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
#override(覆写)父类方法
def speak(self):
print("%s says: I'm %d years old,I'm in %d grade"%(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("my name is %s,i'a speaker.the topic of my speach is %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)
tea = sample("Tim",25,80,4,"python")
tea.speak()#方法名相同,默认调用的是在括号中排前的父类的方法
方法重写
当父类 k方法
不能满足需求时,在子类重写
就是把这个 k方法
重新在子类里写过,名字不变
类属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods
实例 of 私有属性
class JustCounter:
__secretCount = 0 #私有变量
publicCount = 0 #公开变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print(self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCounter)
print(counter.__secretCounter)#执行到这里会报错
私有方法 的 实例
class Site:
def __init__(self,name,url):
self.name = name #public
self.__url = url #private
def who(self)
print('name :',self.name)
print('url :',self.__url)
def __foo(self): #private method
print('this is a private method')
def foo(self)
printf('this is public method')
self.__foo() #在这里,是类的内部,可使用
x = Site('ban','www.ban.com')
x.who()
x.foo()
x.__foo() #error
类的专有方法
__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__truediv__: 除运算
__mod__: 求余运算
__pow__: 乘方
这些专有方法也可以重载(override)