面向对象编程

Posted im.lhc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象编程相关的知识,希望对你有一定的参考价值。

一.类和实例

class  Student(object):
    pass
  1. class后面是类名,类名通常是大写开头的单词

  2. (object) 表示该类是从那个类继承下来的,如果没有合适的继承类,就使用object类,所有类最终都会继承的类

  3. 创建实例:类名+() ,Student()

  4. 可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法

class Student(object):
    def __init__(self,name, score):
        self.name = name
        self.name = score

注意:

  1. __init__ 的第一个参数永远是self,表示创建实例本身,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。

  2. 创建实例时要传参进去

  3. 和普通函数相比,在类定义的函数的第一个参数永远是实例self,调用时不用传该参数,除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。

二.访问控制

如果要让外部不能访问内部的属性和方法,可以把属性的名称前加上两个下划线__, 实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问

class Student(object):
    def __init__(self, name, score):
        self.__name = name
         self.__score = score

可以留一个接口出来访问或者修改实例中的数据

class Student(object):
    ...
?
    def get_name(self):
        return self.__name
?
    def get_score(self):
        return self.__score
    
    def set_score(self,score):
        self.score = score
  1. 变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____score__这样的变量名。

  2. 双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量

bart._Student__name

三.继承和多态

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)

class Animal(object):
    def run(self):
        print(Animal is running)

可以继承上述类

class Cat(Animal):
    pass

判断一个变量是否是某个类型可以用isinstance()判断

isinstance(a, Animal)

多态:

对于一个变量,我们只需要知道它的父类的类型,无需确切知道它的子类型,可以放心调用其方法,而确定调用方法是谁的方法可以在运行中确定。

Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。

四.获取对象信息

1.type()

用来判断对象类型的

  1. type() 返回的是class类型

如果要判断一个对象是否是函数怎么办?可以使用types模块中定义的常量

import types
def fn():
    pass
type(fn) = types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True

2.isinstance()

对于class的继承关系来说,使用type()就很不方便。要判断class的类型,可以使用isinstance()函数

语法:

isinstance(要检测的对象,检测的类型)
#返回结果为True或False

能用type()判断的基本类型也可以用isinstance()判断

isinstance(1, int)
isinstance("a",str)

还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple

isinstance([1,2,3],(list, tuple))

优先使用isinstance()

3.dir()

获取一个对象的属性和方法,返回一个包含字符串的list

获取一个str 类型的属性和方法

dir(str)
?
#[‘__add__‘, ‘__class__‘,..., ‘__subclasshook__‘, ‘capitalize‘, ‘casefold‘,..., ‘zfill‘]

仅仅把属性和方法列出来是不够的,配合getattr()setattr()以及hasattr()

五.实例属性和类属性

实例绑定属性的方法是通过实例变量,或者通过self变量。

class Student(object):
    def __init__(self, name):
        self.name = name

如果在类中绑定属性,直接在class添加属性,这种属性是类属性,归类所有

class Student(object):
    name = "wang"

属性虽然归类所有,但类的所有实例都可以访问到

注意: 不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

以上是关于面向对象编程的主要内容,如果未能解决你的问题,请参考以下文章

面向面试编程代码片段之GC

Scala的面向对象与函数编程

面向对象编程

面向过程编程与面向对象编程

Java面向对象

面向对象编程(OOP)