前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单定义Python和Scala的类和对象

简单定义Python和Scala的类和对象

作者头像
哒呵呵
发布2018-08-06 14:19:18
5450
发布2018-08-06 14:19:18
举报
文章被收录于专栏:鸿的学习笔记

在现代编程语言里,类和对象都是绕不过的话题。对象这个概念可以是生活的抽象,为了更好的理解使用书来做比喻,每一本书都是一个对象,也就是一个实例,书本身具有的页码等等固定不变的东西,就是属于书的性质(属性),而我们对书有着一系列的操作,比如打开书,合上书,在编程语言里称为方法。我们把各种各样的书都可以抽象为一种类型,也就是类。先有类,再有实例,类是对象的蓝本。

我们以书籍为例,先看看如何构建一个类: Scala:

代码语言:javascript
复制
class Book{
    //类的定义
  }

Python:

代码语言:javascript
复制
class Book:
    pass#类的定义

Scala的类使用了{}将整个类的定义包含起来,而Python的类通过缩进符来包含整个类的定义。Scala的Python选取类名的规则都是一样的,采用驼峰式命名,单词的首字母大写。Python的类都继承自object,而Scala的类就是一个纯粹的类。在Scala使用new Book来创建一个实例,而Python使用Book()来实例(实际上是__new__的语法糖)。我们可以在类的定义了加上一些好玩的东西,比如属性和实例。

代码语言:javascript
复制
a = Book.__new__(Book)
isinstance(a,Book)
Out[1]: True

说明一下:为了方便,Scala使用idea作为编辑器,构建一个Test的单例对象运行程序(后面会聊到的,先跳过)。Python使用Spyder作为编辑器,使用if __name__ == 'main':去模拟main方法。因为只是为了讲解概念,会略去很多工程上的细节。

初始化: 书一般都会有书名,假设书名可以区分书的唯一性,在创建实例时必须要给这个实例一个书名,那么如何给Book这个类添加书名这个属性: Scala:

代码语言:javascript
复制
object Test{
  def main(args: Array[String]): Unit = {
    val book = new Book("Hello World!")
    }

  class Book(name:String){
    println(name)
  }
}

Python:

代码语言:javascript
复制
class Book:
    def __init__(self, name:str):
        self.name = name
        print(self.name)

if __name__ == '__main__':
    book = Book("Hello World!")

在Scala的Book类后面的圆括号里跟着一个标识符name(称为类参数),使用这种方法构造的类,要求使用者在刚开始创建这个实例时就必须要提供相应的数据,我们在Book这个类里面加上了println方法,在创建book这个实例时,就会打印出来name这个参数。Python在实例的初始化,使用__init__的内置方法,self是Python的一个习惯命名,因为Python在类方法上都会在第一个参数传入这个类的实例,我们把传入的name赋值给self.name(实例属性),再print出来。

属性: 我们去看一本书,可能会首先大概的翻一翻去获得这个本书的页数pages这个属性。 Scala:

代码语言:javascript
复制
object Test{
  def main(args: Array[String]): Unit = {
    val book = new Book("Hello World!")
    book.pages = 100
    println(book.pages)
    }

  class Book(name:String){
    var pages = 0
    println(name)
  }
}

Python:

代码语言:javascript
复制
class Book:
    pages = 0
    def __init__(self, name:str):
        self.name = name
        print(self.name)

if __name__ == '__main__':
    book = Book("Hello World!")
    book.pages = 100
    print(book.pages)

Scala和Python定义了一个类属性pages,并且在实例化后通过book.pages = 100进行赋值,表示这本叫做Hello World!的书有一百页。值得注意的是Scala我们使用了var变量,而不是val变量,这样就可以在后续代码里对其重新赋与不同的值。

私有属性: 假设这本书你已经写上属于你的独有笔记,不希望别人看到,那么我们可以定义私有属性来防止别人的偷窥。 Scala:

代码语言:javascript
复制
object Test{
  def main(args: Array[String]): Unit = {
    val book = new Book("Hello World!")
    book.pages = 100
    println(book.notes)
    }

  class Book(name:String){
    var pages = 0
    private  var notes = "呵呵哒"
    println(name)
  }
}

Python:

代码语言:javascript
复制
class Book:
    pages = 0
    _notes = "呵呵哒"
    def __init__(self, name:str):
        self.name = name
        print(self.name)

if __name__ == '__main__':
    book = Book("Hello World!")
    book.pages = 100
    print(book.notes)

这时候Scala会报如下错误:

代码语言:javascript
复制
Error:(9, 18) value notes in class Book cannot be accessed in Test.Book
    println(book.notes)

Python会告诉你:

代码语言:javascript
复制
AttributeError: 'Book' object has no attribute 'notes'

Scala通过在变量前面加上private来防止实例化后,有人偷看笔记,而Python则是在notes前面加一个下划线表示这个属性不公开(当然这不是绝对意义上的不公开,要是你知道私有属性存在,无论是Scala还是Python都会有办法看到私有属性)。

方法: 当然笔记不会是无缘无故存在的,我们需要给这本书写上笔记,这个时候我们就需要使用方法,也就是某种操作修改或者写入笔记。 Scala:

代码语言:javascript
复制
object Test{
  def main(args: Array[String]): Unit = {
    val book = new Book("Hello World!")
    book.pages = 100
    book.writeNotes("very good")
    println(book.pages)
    }

  class Book(name:String){
    var pages = 0
    private  var notes = "呵呵哒"
    println(name)
    def writeNotes(note:String):Unit = {
      notes = note
    }
  }
}

Python:

代码语言:javascript
复制
class Book:
    pages = 0
    _notes = "呵呵哒"
    def __init__(self, name:str):
        self.name = name
        print(self.name)

    def write_notes(self, note:str):
        self._notes = note

if __name__ == '__main__':
    book = Book("Hello World!")
    book.pages = 100
    book.write_notes("very good!")
    print(book.pages)

Scala里我们写下了writeNotes方法,它接受外部传过来的参数note,并且将"very good!"重新赋值给notes,而Python则使用write_notes将"very good!"赋值给_notes变量。这里就体现了Scala和Python对于方法命名的小小区别,Scala使用了首字母小写,其余单词开头都是大写,而Python的分隔符使用_。(这里应该要有返回值,表示确实写入成功,为了简便省略了。)

剩下的是独属于Scala的内容了,讲讲单例对象。Scala的类定义里面是不允许存在静态方法的,所以Scala提供了object这种的单例对象,单例对象和类的定义很像,但是单例对象不需要实例化,单例对象本身就是一等的对象,单例对象的名称可以理解为附加在对象的上的名称。如果在同一源码中单例对象和某个类共用名字,那么这个单例对象称为这个类的伴生对象。类和它的伴生对象可以互相访问私有成员。没有同名的类的单例对象称为独立对象,也就是上文中的test这个对象,使用main方法承载,作为程序的入口。(此代码仅仅只是示例,平时不要这么玩)

代码语言:javascript
复制
object Test{
  def main(args: Array[String]): Unit = {
    book1.writeNotes("3")
    }

}

object book1{
  def writeNotes(note:String):Unit = {
    println(note)
  }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
NLP 服务
NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档