欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python基础:一起来面向对象 (一)

程序员文章站 2022-06-15 23:29:17
类,一群有着相同属性和函数的对象的集合 如果你不满足于只做一个+CRUD“码农”,而是想成为一个优秀的工程师,那就一定要积极锻炼直觉思考和快速类比的能力,其是在找不到+bug+的时候 类的示例: class Document(): def __init__(self, title, author, ......

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

  如果你不满足于只做一个+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核心技术与实战》