zoukankan      html  css  js  c++  java
  • Python基础:一起来面向对象 (一)

    类,一群有着相同属性和函数的对象的集合

      如果你不满足于只做一个+CRUD“码农”,而是想成为一个优秀的工程师,那就一定要积极锻炼直觉思考和快速类比的能力,其是在找不到bug的时候
      
      类的示例:
    class Document():
        def __init__(self, title, author, context):
            print('init function called')
            self.title = title
            self.author = author
            self.__context = context # __ 开头的属性是私有属性
    
        def get_context_length(self):
            return len(self.__context)
    
        def intercept_context(self, length):
            self.__context = self.__context[:length]
    
    harry_potter_book = Document('Harry Potter', 'J. K. Rowling', '... Forever Do not believe any thing is capable of thinking independently ...')
    
    print(harry_potter_book.title)
    print(harry_potter_book.author)
    print(harry_potter_book.get_context_length())
    
    harry_potter_book.intercept_context(10)
    
    print(harry_potter_book.get_context_length())
    
    print(harry_potter_book.__context)
    
    ########## 输出 ##########
    
    init function called
    Harry Potter
    J. K. Rowling
    77
    10
    
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-5-b4d048d75003> in <module>()
         22 print(harry_potter_book.get_context_length())
         23 
    ---> 24 print(harry_potter_book.__context)
    
    AttributeError: 'Document' object has no attribute '__context'

    三问对象

      1.如何在一个类中定义一些常量,每个对象都可以方便访问这些常量而不用重新构造?

      答: 一般写成大字,与函数并列声明并赋值,注意是可以修改的。

      2.如果一个函数不涉及到访问修改这个类的属性,而放到类外面有点不恰当,怎么做才能更优雅呢?

      答: classmethod装饰器声明函数为类函数,最常用的功能用于定义不同的init函数,如create_empty_book函数创建的对象 context一定为'nothing',这比直接构造要清晰一些.

           staticmethod装饰器声明函数为静态函数,可以用来做一些简单独立的任务

    class Document():
        
        WELCOME_STR = 'Welcome! The context for this book is {}.'
        
        def __init__(self, title, author, context):
            print('init function called')
            self.title = title
            self.author = author
            self.__context = context
        
        # 类函数
        @classmethod
        def create_empty_book(cls, title, author):
            return cls(title=title, author=author, context='nothing')
        
        # 成员函数
        def get_context_length(self):
            return len(self.__context)
        
        # 静态函数
        @staticmethod
        def get_welcome(context):
            return Document.WELCOME_STR.format(context)
    
    
    empty_book = Document.create_empty_book('What Every Man Thinks About Apart from Sex', 'Professor Sheridan Simove')
    
    
    print(empty_book.get_context_length())
    print(empty_book.get_welcome('indeed nothing'))
    
    ######### 输出 ##########
    
    init function called
    7
    Welcome! The context for this book is indeed nothing.

      3.既然类是一群相似的对象的集合,那么可不可以是一群相似的类的集合呢?

    • 继承类在生成对象时不会自动调用父类的构造函数,必须在init()函数中显式调用父类中的构造函数 Entity.__init__(self, 'document')
    • 当子类对象调用 get_context_length 函数时,如果没有实现此函数,会抛出get_context_length not implemented异常,这就使子类必须实现此函数。
    • 父类中的print_title 函数体现了继承的优势,减少重复代码.
    class Entity():
        def __init__(self, object_type):
            print('parent class init called')
            self.object_type = object_type
        
        def get_context_length(self):
            raise Exception('get_context_length not implemented')
        
        def print_title(self):
            print(self.title)
    
    class Document(Entity):
        def __init__(self, title, author, context):
            print('Document class init called')
            Entity.__init__(self, 'document')
            self.title = title
            self.author = author
            self.__context = context
        
        def get_context_length(self):
            return len(self.__context)
        
    class Video(Entity):
        def __init__(self, title, author, video_length):
            print('Video class init called')
            Entity.__init__(self, 'video')
            self.title = title
            self.author = author
            self.__video_length = video_length
        
        def get_context_length(self):
            return self.__video_length
    
    harry_potter_book = Document('Harry Potter(Book)', 'J. K. Rowling', '... Forever Do not believe any thing is capable of thinking independently ...')
    harry_potter_movie = Video('Harry Potter(Movie)', 'J. K. Rowling', 120)
    
    print(harry_potter_book.object_type)
    print(harry_potter_movie.object_type)
    
    harry_potter_book.print_title()
    harry_potter_movie.print_title()
    
    print(harry_potter_book.get_context_length())
    print(harry_potter_movie.get_context_length())
    
    ########## 输出 ##########
    
    # Document class init called
    # parent class init called
    # Video class init called
    # parent class init called
    # document
    # video
    # Harry Potter(Book)
    # Harry Potter(Movie)
    # 77
    # 120

    抽像类的使用

      抽象类是为父类而生的,不能对象化。如果有抽象函数也必须在子类中重写才能使用。

    from abc import ABCMeta, abstractmethod
    
    class Entity(metaclass=ABCMeta):
        @abstractmethod
        def get_title(self):
            pass
    
        @abstractmethod
        def set_title(self, title):
            pass
    
    class Document(Entity):
        def get_title(self):
            return self.title
        
        def set_title(self, title):
            self.title = title
    
    document = Document()
    document.set_title('Harry Potter')
    print(document.get_title())
    
    entity = Entity()
    
    ######### 输出 ##########
    Harry Potter
    
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-7-266b2aa47bad> in <module>()
         21 print(document.get_title())
         22 
    ---> 23 entity = Entity()
         24 entity.set_title('Test')
    
    TypeError: Can't instantiate abstract class Entity with abstract methods get_title, set_title

    参考:

      极客时间《Python核心技术与实战》

      

  • 相关阅读:
    SQL Server 2008 数据库回滚到某个时间点
    SQL Server 2008以上误操作数据库恢复方法——日志尾部备份
    C# BindingSource
    何谓SQL Server参数嗅探
    mongodb获取具体某一天的查询语句
    给MongoDB添加索引
    MongoDB 学习笔记四 C#调用MongoDB
    Access MongoDB Data with Entity Framework 6
    Ruby 和 OpenSSL CA 证书的问题
    解决方法:配置群集时# gem install redis 报错:Unable to require openssl, install OpenSSL and rebuild ruby
  • 原文地址:https://www.cnblogs.com/xiaoguanqiu/p/10973001.html
Copyright © 2011-2022 走看看