
本文共 1718 字,大约阅读时间需要 5 分钟。
对象编程语法基础
当我们开始学习Python时,最初的困惑往往来自于名称空间的理解。有时候我们可能会想,为什么会有双下划线__?是不是说内置变量就是这样写的?其实,这只是Python对私有变量的一种实现方式。双下划线的作用是提示,这些变量不能直接从外面访问。但是这并不意味着完全没有办法访问它们,后面我们会提到相关方法。
访问限制
在握手套用语中,当我们创建一个类,比如Student,可能需要保护一些内部属性,防止外部代码随便修改。为了实现这一点,Python提供了一种简单的方式:在属性的名称前后加上双下划线。例如,John这个属性可以写成__name,这样只有类内部的人才能直接访问。
但是,问题来了。如果外部代码想要获取name和score,这该怎么办?其实很简单,我们可以为Student类添加get_name和get_score这样的方法供外部调用。还有,如果允许外部代码修改score,我们可以再添加一个set_score方法。
需要注意的是,有些时候double underscore(__)开头的变量在Python中会有特殊行为。例如,__name变量会被解释器自动改成_Student__name。这一点需要特别注意,强烈建议不要依赖这种方法来访问私有变量,因为这可能会导致与解释器的差异。
继承和多态
在面向对象编程中,继承和多态是非常基础的概念。继承的意思是允许我们创建一个新类,这个新类可以继承已有的类的属性和方法。例如,Dog可以继承自Animal,Cat可以继承自Animal。这种做法的好处是子类可以利用父类的功能,同时也可以新增自己的方法。
多态的含义则是,一个函数可以对多种不同的对象类型适用。比如说run_twice函数可以接收Animal、Dog、Cat等多个类型的实例,并调用它们的run方法。这就让我们的代码更加灵活,不用每次修改函数就能适用于新类型。
开闭原则
当我们设计一个系统时,开闭原则可以帮助我们避免修改已有代码。对于变量而言,我们不关心它具体是什么类型,只要它有run方法就可以使用。这样做的好处是,当我们新增一种Animal的子类时,只需要确保它有一个run方法,就能不用修改现有的代码。这种设计理念源自于多态的优势。
静态语言与动态语言
在静态语言(如Java)中,当你定义一个变量,假设类型是Animal,你必须确保传入的对象确实是Animal类型或它的子类,否则可能会抛出错误。Python则不然,属于动态语言。传入的对象只需要有一个run方法,Python就会自动调用它。这种灵活性来自于鸭子类型的理念—— mocker it until it quacks like a duck(等待它像鸭子一样叫,直到它确实像鸭子)。这也意味着在运行时,我们不需要知道对象的具体类型,这给予了更大的灵活性。
获取对象信息
学习Python的另一个重要技能是获取对象信息。使用type()函数可以知道一个对象的类型,而isinstance()函数可以测试一个对象是否属于某个类型。这样我们可以做很多有趣的事情,比如判断某个变量是否是list或者tuple。
此外,dir()函数可以帮助我们获取一个对象所有的属性和方法。例如,在Jython中,可以使用dir()查看字符串的所有方法。但请注意,这些方法只是名字的列表,并不一定直接告诉我们能做什么。
实例属性与类属性
在Python中,属性分为实例属性和类属性。类属性是属于整个类的,而实例属性则属于每个实例自己的。我一般建议在初始化对象时,用实例属性存储那些需要根据具体情况改变的值,而用类属性存储那些所有对象都相同的属性。这样不仅更安全,而且也更节省内存。
此外,当你在类中定义了一个属性名,实例可能会绑定一个实例属性来覆盖它。为了避免这个问题,我们可以使用self.class.属性名,这样就能访问类属性了。这点在设计类时尤为重要,以免实例属性与类属性混淆。
最后,记住,Python对方法的访问是动态的,这意味着我们可以随时给对象添加新属性和方法。这是Python灵活性的体现,但也意味着我们需要谨慎设计,以免造成继承问题。
发表评论
最新留言
关于作者
