python面向对象(上)


先上个例子:

class Student: # 类名,同时创建同名的类对象和变量,类对象只能有一个
    school='yyds' #类属性
    def show(self,id,name,age,school): # 第一个参数必须是self,指的是当前类的实例
        self.id=id# name,id,age是实例属性
        self.name=name
        self.age=age
        self.school=school
        print(self.id,self.name,self.age)# 创建一个实例

命名规则

创建类的时候命名有以下几个规则:
1:用class关键字来定义类,命名格式如上
2:类名的首字母应大写,如上的Student(不是强制的,但是是一般的命名规则,这样命名不会出错)
3:方法命名的时候如果有多个单词第一个单词首字母不用大写,其余的单词首字母大写
4:我们再给属性或方法命名的时候通过下划线来表示变量的类别:_foo(左边有一个下划线),表示只允许本身及其子类应用;__foo(左边有两个下划线,表示是私有类型),只允许这个类本身访问; __ foo __(左右各有两个下划线,表示python的内置函数)
一个类主要由以下六个要素组成:
类对象、实例对象、类属性、实例属性、类方法、实例方法。

对象的创建

创建类对象

以上已经说明,用(class+类名)创建,创建类名的同时还自动创建类对象和量,名称就是类名称,这里要注意的是类对象只能有一个。

创建实例对象

实例对象通过调用类对象来创建,如下所示:

s1=Student() #创建一个实例对象,继承其所有的实例方法

通过以上的代码,我们创建了一个实例对象,这里实例对象会继承所有的实例方法,实例属性等
如果类中有相同的类属性和实例属性,那么通过实例对象只能访问实例属性,如下所示的代码:

class Student:
    school='yyds'
    def say(self,school):
        self.school=school
s1=Student()
s1.say('ohhh')
print(s1.school,Student.school)

以上的话我们运行可以发现,用s1得到的是ohhh,用Student得到是yyds,这里我们可以理解为局部变量的优先级大于全局变量,两者尽量不要有重名

修改增加类属性

此外,我们还可以修改或增加类对象与实例对象的属性,如下所示的代码:

class Student:
    school='yyds'
    def say(self,school):
        self.school=school
s1=Student()
s1.say('ohhh')
s1.age=11
s1.name='小明'
Student.age=111
print(s1.age,s1.name,Student.age)

我们在这里对s1增加了age与name属性,对Student增加了age属性,输出的与增加的相同

构造方法

构造实例方法

要注意的一点是实例方法的第一个变量永远是self,其后面跟着定义的是其余的自定义的变量。
我们这里先说一种特殊的方法定义:对于__init__ 的重写,python在创建对象的时候默认是存在init的,但是如果我们想对初始化重新写的话,就可以加入一个对于以上__init__的重写,也可以带变量,但是在调用创建的时候也要带变量。
如下图代码所示:

不带变量

class Student:
    school='yyds'
    def __init__(self):
        self.name='111'
        self.age=16
        self.school='ohhh'
s1=Student()
print(s1.name,s1.age,s1.school)

这个是不带变量的,下面是输出:
在这里插入图片描述

带变量

class Student1:
    school='yyds'
    def __init__(self,name,age,school):
        self.name=name
        self.age=age
        self.school=school
s2=Student1('yyds',16,'ohhh')
print(s2.school,s2.name,s2.age)

这是带变量的,下面是输出结果
在这里插入图片描述
当然也可以构造很多其他的方法,构造的形式和以上类似,但要注意的一点是第一个变量永远是 self
我们再来一个实例方法的例子

构造方法小例子

class Student:
    student_num=0
    def add(self,name):
        print('增加了一名新同学,名字叫:%s'% name)
        Student.student_num+=1
s1=Student()
s1.add('yyds')
print(s1.student_num)
s2=Student()
s2.add('ohhh')
print(s2.student_num)

我们可以看出来在一个代码中,每创建一个类属性,类变量不会清零,而是递加的

构造类方法

很简单,就是在方法的上面加上一个@classmethod,但是第一个变量是cls,类变量可以调用,通过cls可以访问相关的类属性,但是不能访问实例属性,如下面的代码所示:

class Student:
    student_num=0
    def add(self,name):
        print('增加了一名新同学,名字叫:%s'% name)
        Student.student_num+=1
    @classmethod
    def sub(cls,name):# 这里的cls只能访问类属性,不能访问实例属性
        print('转走了一个学生,名字为:%s'% name)
        cls.student_num-=1
s1=Student()
s1.add('yyds')
print(s1.student_num)
s2=Student()
s2.add('ohhh')
print(s2.student_num)
Student.sub('ohhh')
print(Student.student_num)

构造静态方法

在程序的前面加一个@staticmethod
静态方法可以访问类属性,但不可以访问实例属性

class Student():
    num=0
    def __init__(self,myName):
        Student.num+=1
        self.name=myName
    @staticmethod
    def count():
        print('学生个数:%d'%Student.num)
Student.count()
s1=Student('小千')
s1.count()
s2=Student('小峰')
s1.count()

下面是输出结果:
在这里插入图片描述

运算符的重载

比较运算符重载

class MyComplex:
    def __init__(self,r=0,i=0): # 构造方法
        self.r=r
        self.i=i
    def __add__(self, other): # 重载乘运算
        return MyComplex(self.r+other.r,self.i+other.i)
    def __sub__(self, other): # 重载减运算
        return MyComplex(self.r-other.r,self.i-other.i)
    def __mul__(self, other): # 重载乘运算
        return MyComplex(self.r*self.r,other.i*other.i)
    def __truediv__(self, other): # 重载除运算
        return MyComplex(
            (self.r*other.r+self.i*other.i)/(other.r**2+other.i**2),
            (self.i*other.r-self.r*other.i)/(other.r**2+other.i**2)
        )
    def show(self): # 设置输出的格式
        if self.i<0:
            print('(',self.r,self.i,'j',')',sep='')
        else:
            print('(',self.r,'+',self.i,'j',')',sep='')
c1=MyComplex(6,-8)
c2=MyComplex(1,-1)
(c1+c2).show()
(c1-c2).show()
(c1*c2).show()
(c1/c2).show()

下面是输出:
在这里插入图片描述

字符串重载

当对象作为str()或者print()的参数时,该对象会调用重载的__str__ 方法,所以我们在类中重载了str之后,该类加减的时候会直接返回我们定义的输出形式

class MyComplex:
    def __init__(self,r=0,i=0):# 构造方法
        self.r=r
        self.i=i
    def __str__(self):
        if self.i<0:
            return '('+str(self.r)+str(self.i)+'j)'
        else :
            return '('+str(self.r)+'+'+str(self.i)+'j)'
c1=MyComplex(6,-8)
c2=MyComplex(1,2)
print(c1,str(c2))

索引或切片重载

当对实例对象执行索引、分片或迭代时,该对象会调用__getitem__()方法

class Data:# 定义一个数据类
    def __init__(self,list):
        self.data=list[::-1]
    def __getitem__(self, item): # 重载索引与分片
        return self.data[item]
data=Data([1,2,3,4,5])
print(data[2])
print(data[1:])
for i in data:
    print(i,end=' ')

索引或切片重载

用setitem来是实现对对象的修改

class Data:# 定义一个数据类
    def __init__(self,list):
        self.data=list[::-1]
    def __setitem__(self, key,value): # 重载索引与分片
        self.data[key]=value
data=Data([1,2,3,4,5])
print(data.data)
data.data[1]='千千万万'
data.data[2:]='you are a little cow horse'
print(data.data)

检查成员重载

class Data:# 定义一个数据类
    def __init__(self,list):
        self.data=list[::-1]
    def __contains__(self, item): # 重载索引与分片
        return item in self.data
data=Data([1,2,3,4,5])
print(1 in data.data)

重载小结

总结一下:重载就是先创建一个类,然后我们在里面定义重载的符号,我们在要建一个实例对象来表达我们要计算的数,然后实例对象之间的计算就是来根据重载符来计算的

持续更新中~~~~~~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值