Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 以最正确的方式继承类实例属性_Python_Class_Oop - Fatal编程技术网

Python 以最正确的方式继承类实例属性

Python 以最正确的方式继承类实例属性,python,class,oop,Python,Class,Oop,我有很多书,分为章节,所以我决定为Book创建一个简单的类。课程如下: 课程手册: 定义初始化(self,标题:str=None,类型:str=None,章节:str=None) self.title=标题 self.type=type self.chapter=章 每本书唯一变化的变量是章节名称。在我的完美世界中,我想创建第一个实例: class Book: def __init__(self, title:str = None, type:str = None, chapter

我有很多书,分为章节,所以我决定为
Book
创建一个简单的类。课程如下:

课程手册:
定义初始化(self,标题:str=None,类型:str=None,章节:str=None)
self.title=标题
self.type=type
self.chapter=章
每本书唯一变化的变量是章节名称。在我的完美世界中,我想创建第一个实例:

class Book:
    def __init__(self, title:str  = None, type:str  = None, chapter:str  = None):
        self.title = title
        self.type = type
        self.chapter = chapter
    
    @classmethod
    def from_other_book(cls, chapter, book):
        return cls(title=book.title, type=book.type, chapter=chapter)


book1 = Book("Title", "book", "Chapter one")
book2 = Book.from_other_book("Chapter two", book)
book1=书(“标题”、“书”、“第一章”)
然后只需克隆实例并更改其章节属性:

book2=book1
book2.chapter=“第二章”
但是,当
book1.chapter
属性也在更改时,它将不起作用

所以我必须做一些类似的事情:

从副本导入副本
book2=副本(book1)
book2.chapter=“第二章”

book2=Book()
第2册。更新(第1册。更新)
book2.chapter=“第二章”

我是一名新的程序员,我想知道这是唯一的方法,还是我可以让代码不那么笨拙&不需要导入?

一个想法是创建一个合适的界面,在以前的基础上获得一本新书。用Python术语来说,您可以编写一个
classmethod
,它基于另一个实例返回一个新的
Book
实例:

class Book:
    def __init__(self, title:str  = None, type:str  = None, chapter:str  = None):
        self.title = title
        self.type = type
        self.chapter = chapter
    
    @classmethod
    def from_other_book(cls, chapter, book):
        return cls(title=book.title, type=book.type, chapter=chapter)


book1 = Book("Title", "book", "Chapter one")
book2 = Book.from_other_book("Chapter two", book)
编辑:我的回答回答了您的问题,尽管我同意@ForceBru在OP中的评论-一本新的
实例不应代表同一本书的新章节。

对章节标题进行编辑,然后在创建书籍时通过它们。您可以使用列表理解来简洁地写出以下内容:

课程手册:
定义初始化(self,标题:str=None,类型:str=None,章节:str=None):
self.title=标题
self.type=type
self.chapter=章
章节=[“第一章”、“第二章”、“第三章”]
书籍=[章节中章节名称的书籍(“标题”、“书籍”和章节名称)]
如果需要单独的变量,这也是可行的:

(第1册、第2册、第3册)=(章节中章节名称的书(“标题”、“书”和章节名称)

使用
copy
deepcopy
是最简单的方法,它绝对不会让你的代码变得笨拙。你可以做
book2=Book(book1.title,book1.type,“第二章”)
。但我认为这里有一个逻辑缺陷:一本
书应该由许多章节组成,而不是一章。特别奇怪的是,你把
book1
的标题复制到另一本
书中,并将其键入另一本
书中:这些书。。。不知何故,同一本书的一部分(因为相同的标题和类型)?当您将book2和book1设置为相等时,它们指向内存中的相同地址空间(相同的对象)。调用copy时,您正在创建该对象的第二个实例,该对象在内存中有自己的地址(这是您想要的)。通过这种方式,您可以在自己的内存空间中修改book2的对象,而不会打扰book1。我同意ForceBru的观点,如果有多个
Book
对象与一个书名关联,则类
Book
的命名非常混乱。@ForceBru事实上,我有更复杂的图书结构和每个“章节”是~800页及以上的部分,涵盖一些基本主题,分为子主题。但为了简单起见,我写了这样的例子来说明我的主要问题。我喜欢这个解决方案(在元组中有单独的变量),因为它不使用导入,也不需要在类中使用额外的方法。