Fork me on GitHub

类及对象初体验

一、类创建

class Animal:

    def setName(self,name):
        self.name=name

    def getName(self):
        return self.name

#创建动物猫的对象
cat=Animal()
cat.setName("cat")
#调用cat对象的属性name
print(cat.name)
#调用cat方法的getName方法
print(cat.getName())
#调用cat方法的getName方法 另一种方式
print(Animal.getName(cat))
  • 类的创建使用关键字class定义,类名跟在class之后
  • 类中的方法就是函数
  • 每一个方法中的第一个参数都是self,如果方法中有多个参数,第一个参数将作为self参数使用,在调用方法时,这个参数不用自己传入,系统会将方法所属的对象传入这个参数。
  • 调用对象方法的方式有两种,一种是直接通过对象调用;另一种是通过类调用,并且传入相应的对象。

 二、方法的私有化

  在Java这类语言中提供了private关键字,进行方法或者变量的私有化,但是在python中并没有提供,不过可以使用其它方式来达到这种效果,在python类的方法名前面加上“__”,可以杜绝外部访问这个类中的方法。

class FOO:

    def f1(self):
        return "我是f1"

    def __f2(self):
        return "我是f2"

    #类的内部是可以调用私有方法的
    def f3(self):
        return self.__f2()

f=FOO()
f.f1()
f.__f2() #AttributeError: 'FOO' object has no attribute '__f2'

  可以看到f2是私有方法,类外部不能进行访问,否则会抛出异常,而在类的内部是可以调用私有方法的。

  f2是否是真的在类外部不能调用了呢?当然不是,实际上python编译器遇到"__"开头的方法会将方法名变成“_ClassName__MethodName”,照着这种形式调用,是可行的。

...

print(f._FOO__f2())#我是f2

...

  另外,如果想查看类中的所有方法,应该如何做呢?

import inspect
methods=inspect.getmembers(f,predicate=inspect.ismethod)
print(methods)#[('_FOO__f2', <bound method FOO.__f2 of <__main__.FOO object at 0x0000000000676F28>>), 
        #('f1', <bound method FOO.f1 of <__main__.FOO object at 0x0000000000676F28>>), 
        #('f3', <bound method FOO.f3 of <__main__.FOO object at 0x0000000000676F28>>)]

三、类的继承

  类的继承就是一个类从另一个类中获得所有的成员,父类的成员可以在子类中使用。新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类。

class A:
    pass

class B:
    pass

class C(A): #单继承 C是派生类,A是基类
    pass

class D(A,B):#多继承,继承多个类,中间以逗号分隔开
    pass

  D类中会按照从左到右的顺序继承A类、B类中的成员,如果多个父类中有相同的成员,会按照父类书写的顺序继承,也就是说前面的父类会覆盖写在后面父类同名的方法。

四、检测继承关系

  有时需要判断类与类之间是否有继承关系,这样可以利用父类中的方法,那么这种继承关系应该如何判断呢?可以使用issubclass函数进行判断,它接收2个参数,第一个是子类,第二个是父类,如果是继承关系返回True,否则返回False,间接的继承关系也是适用的。

class Fruits:
    pass

class Apple(Fruits):
    pass

print(issubclass(Apple,Fruits))#True

   如果获取已知类的父类们,可以直接使用"__bases__",这是类的一个特殊属性

class Fruits:
    pass

class Apple(Fruits):
    pass

print(Apple.__bases__)#(<class '__main__.Fruits'>,)

五、类、类成员、对象的判断

a、hasattr()

判断对象或者类中是否存在某个成员

class Bar:

    def f1(self):
        pass
b=Bar()
print(hasattr(b,"f1"))#True
print(hasattr(Bar,"f1"))#True

b、getattr()

获取类中或对象中成员的值,它有三个参数第三个参数用于制定默认值

class Bar:

    def f1(self):
        pass
b=Bar()

print(getattr(Bar,"f1"))#<function Bar.f1 at 0x0000000000535BF8>

c、setattr()

用于设置对象中成员的值,setattr函数有三个参数,前两个与getattr相同,第三个参数用于指定成员的值

#如果对象中有name属性,则更新该值,如果没有,会添加一个新的name属性,也可以更新或者添加类属性
setattr(b,"name","bright")
print(b.name)#bright

动态添加函数

class Bar:

    def f1(self):
        pass
b=Bar()

####类添加f2函数####
def f2():
    print("动态添f2")
setattr(Bar,'f2',f2)
Bar.f2()  #类调用

####对象添加f2函数###
def f2():
    print("动态添f2")
setattr(b,'f2',f2)
b.f2()  #对象调用

d、isinstance

用于判断实例和类之间的关系

class A:
    print("A")

class B(A):
    print("B")

a=A()
b=B()

print(isinstance(a,A))#True
print(isinstance(b,A))#True

 六、多态

同类对象的多种形态,应用多态增加了程序的灵活性、扩展性。

实现多态的步骤:

  • 定义新的子类
  • 重写对应的父类方法
  • 使用子类的方法直接处理,不调用父类的方法
class Animal:

    def eat(self):
        pass

    def run(self):
        pass

class Dog(Animal):

    def run(self):
        pass

简单的来说,Dog是新定义的子类,不想调用父类的run方法,需要执行自己的run方法,这就是多态,一个类产生的多个对象,调用同一个方法,产生不同的执行结果。

 

posted @ 2019-06-22 19:02  iveBoy  阅读(290)  评论(0编辑  收藏  举报
TOP