python类讲解

简单的类的举例:

class Person:

    def set_name(self, name): # self相当于java中的this

        self.name=name

    def get_name(self):

        return self.name;

    def greet(self):

        print("hello,i'm %s" % self.name)

 

person=Person()

person.set_name('liuyifan')

解释器会转换为Person.set_name(person, 'liuyifan')。从这里可以看出方法定义时为什么需要self了。

person.get_name()

person.greet()

 

#Student是Person的子类,

# class Student(Person, Class2):这样就可以同时继承两个类

class Student(Person):

    def set_grade(self,grade):

        self.grade=grade

    def get_grade(self):

        return self.grade

    #这里重写了父类中的方法

    def greet(self):

        print("hello,i'm %s. I'm a student." % self.name)

student=Student()

student.set_name('anddrew')

print(student.get_name())

student.set_grade(8)

print(student.get_grade())

print(student.greet())

 

类实例化时收到的参数传入__init__()。__init__()不能有返回值。

如果子类没有定义__init__(),则子类实例化时会调用父类的__init__()。如果子类定义了__init__(),则子类实例化时不会调用父类的__init__()。如果想要调用,需要在子类的__init__()中通过super().__init__()来调用。

 

__init__()外定义的属性,是类属性。可以通过直接使用类名调用,也可以使用类的对象来调用。看起来不同对象可以对类属性赋不同的值,但是这其实是生成了新的实例属性,并不会影响类属性的值。__init__()中定义的属性,是实例属性,不能通过类名调用。其它方法里也可以定义实例属性和类属性。但是只有当这些方法被调用后这些实例属性和类属性才能使用。如果方法内的定义的变量前面没有self和cls,则是局部变量。

class c1:

    a1=1 #定义了类属性,类被定义时,这个类属性就被创建了。

    def __init__(self,a2):

        self.a2=a2 #定义了实例属性,在类被实例化时这个实例属性被创建。

    def m1(self):

        self.a3=3 #定义了实例属性,但是只有到m1被调用时,这个实例属性才被创建。

        a4=4 #定义了局部变量

                  return a4*a4

    @classmethod   

    def m2(cls):

        cls.a5=5 #定义了类属性,但是只有到m2被调用时,这个类属性才被创建。

 

也可以在类外面定义类变量(class_name.var_name)和实例变量。也可以在类外面使用。

 

python中没有publicprotectedprivate关键字。

不以下划线开头的成员和方法是public的。

protected成员和方法以一个下划线开头_

私有成员和私有方法以两个下划线开头__

其实python本质上并没有进行权限控制,这只不过是一种书写的惯例,程序员仍然可以随意访问以一个下划线或者双下划线开头的成员和方法。程序员在访问时自己确认这样访问是否合适。

 

python的类有很多特殊方法。比如object1=class1(args),其实是首先使用特殊方法__new__()(构造函数)来创建对象,之后调用特殊方法__init__()(初始化函数)来初始化一个对象。比较两个对象object1==object2,实际上调用特殊方法__eq__()。因为特殊方法的名字是固定的,所以子类中如果要调用父类的特殊方法,需要使用super().__eq__()这种方式。再比如内建类型都有__copy__()。

Python的类还有很多特殊属性,特殊方法和特殊属性都是以两个下划线开头和结尾的。比如__class__查看对象所在的类,__name__是所属对象的名字,__file__是当前文件的完整路径,__package__表示模块所在的包,__all__制定模块导入时的限制。比如:object1.__class__.__name__可以得知object1所属的类的名字。

 

@property可以将方法变成属性。使用@name.setter来实现对应的setter,可以实现对属性赋值的检查。例如:

class Person:

    def __init__(self,age):

        self.age=age

    @property

    def age(self):

        return self.__age #当然这里也可以写逻辑,通过逻辑获得返回值。

    @age.setter

    def age(self,age):

        assert age>0 , "Age must positive"

        self.__age = age

Person=Person(-1)

因为__init__()中self.age=age,也会接受age.setter的检查,所以抛出异常,AssertionError: Age must positive。

 

#定义类方法

@classmethod

def cm(cls):

print(cls.z)

#定义静态方法

@staticmethod

def sm():

print("I'm a staticmethod()")

类方法和静态方法除了可以使用实例来调用(实际上只关注其所属的类),还可以直接使用类来调用。

类方法有cls做参数,静态方法不需要cls做参数。静态方法不使用所在类的属性和方法。

也可以在类外面添加实例方法、类方法和静态方法。定义和类内部方式相同,只是还需要一个赋值语句。

比如实例方法:

def instance_fun(self):

class_name.fun= instance_fun

则为类添加了一个fun()方法。

如果使用object_name.fun= instance_fun,则这个方法仅对这个对象有效。

del可以删除类变量和实例变量,也可以删除实例方法、类方法和静态方法。

 

继承抽象基类ABC的类是抽象类,它提供类似java的接口的功能。抽象类不能实例化,其职责是定义子类应该实现的一组抽象方法。

 

内置函数hasattr(object, name)用来判断对象是否包含对应的属性。如果包含在返回True,否则返回False。

内置函数getattr(object, name[, default]) 用来获取属性值,如果属性不存在,如果提供了default,否则抛出AttributeError。

内置函数setattr(object, name, value)为属性赋值。如果属性不存在,则创建一个属性,进行赋值。

getattr()和setattr()相比于通过object.name直接读写属性没有提供额外功能,但是为编程提供了额外的灵活性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值