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核心技术与实战》