Hướng dẫn class in another class python - lớp trong một lớp trăn khác

Những gì tôi đang nói ở đây là các lớp học lồng nhau. Về cơ bản, tôi có hai lớp mà tôi đang làm người mẫu. Một lớp tải xuống và lớp tải xuống. Khái niệm OOP rõ ràng ở đây là sáng tác. Tuy nhiên, thành phần không nhất thiết có nghĩa là làm tổ, phải không?

Tôi có mã trông giống như thế này:

class DownloadThread:
    def foo(self):
        pass

class DownloadManager():
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadThread())

Nhưng bây giờ tôi đang tự hỏi liệu có tình huống làm tổ sẽ tốt hơn không. Cái gì đó như:

class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())

0

Bạn có thể muốn làm điều này khi lớp "bên trong" là một lần, sẽ không bao giờ được sử dụng bên ngoài định nghĩa của lớp bên ngoài. Ví dụ: sử dụng một metaclass, đôi khi nó tiện dụng để làm

class Foo(object):
    class __metaclass__(type):
        .... 

Thay vì xác định một metaclass một cách riêng biệt, nếu bạn chỉ sử dụng nó một lần.

Lần duy nhất khác tôi đã sử dụng các lớp lồng nhau như vậy, tôi chỉ sử dụng lớp bên ngoài làm không gian tên để nhóm một loạt các lớp liên quan chặt chẽ với nhau:

class Group(object):
    class cls1(object):
       ...

    class cls2(object):
       ...

Sau đó, từ một mô -đun khác, bạn có thể nhập nhóm và gọi chúng là nhóm.CLS1, Group.CLS2, v.v. Tuy nhiên, người ta có thể lập luận rằng bạn có thể hoàn thành chính xác giống nhau (có lẽ theo cách ít khó hiểu hơn) bằng cách sử dụng mô -đun.

Đã trả lời ngày 17 tháng 9 năm 2008 lúc 1:12Sep 17, 2008 at 1:12

Hướng dẫn class in another class python - lớp trong một lớp trăn khác

3

Tôi không biết Python, nhưng câu hỏi của bạn có vẻ rất chung chung. Bỏ qua tôi nếu nó cụ thể với Python.

Lớp học là tất cả về phạm vi. Nếu bạn nghĩ rằng một lớp sẽ chỉ có ý nghĩa trong bối cảnh của một người khác, thì trước đây có lẽ là một ứng cử viên tốt để trở thành một lớp lồng nhau.

Nó là một mô hình phổ biến làm cho các lớp trợ giúp như các lớp riêng tư, lồng nhau.

Đã trả lời ngày 17 tháng 9 năm 2008 lúc 1:14Sep 17, 2008 at 1:14

Hướng dẫn class in another class python - lớp trong một lớp trăn khác

André Chalellaandré ChalellaAndré Chalella

13.4K10 Huy hiệu vàng53 Huy hiệu bạc61 Huy hiệu Đồng10 gold badges53 silver badges61 bronze badges

1

Có một cách sử dụng khác cho lớp lồng nhau, khi người ta muốn xây dựng các lớp kế thừa có chức năng nâng cao được gói gọn trong một lớp lồng nhau cụ thể.

Xem ví dụ này:

class foo:

  class bar:
    ...  # functionalities of a specific sub-feature of foo

  def __init__(self):
    self.a = self.bar()
    ...

  ...  # other features of foo


class foo2(foo):

  class bar(foo.bar):
    ... # enhanced functionalities for this specific feature

  def __init__(self):
    foo.__init__(self)

Lưu ý rằng trong hàm tạo của foo, dòng self.a = self.bar() sẽ xây dựng một

class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
0 khi đối tượng được xây dựng thực sự là một đối tượng foo và đối tượng
class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
2 khi đối tượng được xây dựng thực sự là một đối tượng
class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
3.

Nếu lớp

class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
4 được xác định bên ngoài lớp foo, cũng như phiên bản di truyền của nó (ví dụ sẽ được gọi là
class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
6), thì việc xác định lớp mới
class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
3 sẽ đau hơn nhiều Dòng đầu tiên được thay thế bằng
class DownloadManager():
    class DownloadThread:
        def foo(self):
            pass
    def __init__(self):
        dwld_threads = []
    def create_new_thread():
        dwld_threads.append(DownloadManager.DownloadThread())
9, ngụ ý viết lại toàn bộ hàm tạo.

1

Bạn có thể sử dụng một lớp làm trình tạo lớp. Thích (trong một số mã Cuff :)

class gen(object):
    class base_1(object): pass
    ...
    class base_n(object): pass

    def __init__(self, ...):
        ...
    def mk_cls(self, ..., type):
        '''makes a class based on the type passed in, the current state of
           the class, and the other inputs to the method'''

Tôi cảm thấy như khi bạn cần chức năng này, nó sẽ rất rõ ràng với bạn. Nếu bạn không cần phải làm điều gì đó tương tự hơn thì có lẽ nó không phải là trường hợp sử dụng tốt.

Hướng dẫn class in another class python - lớp trong một lớp trăn khác

Tim Cooper

155K37 Huy hiệu vàng322 Huy hiệu bạc275 Huy hiệu Đồng37 gold badges322 silver badges275 bronze badges

Đã trả lời ngày 17 tháng 9 năm 2008 lúc 1:34Sep 17, 2008 at 1:34

tim.tadhtim.tadhtim.tadh

8696 Huy hiệu bạc16 Huy hiệu Đồng6 silver badges16 bronze badges

Thực sự không có lợi ích gì khi làm điều này, ngoại trừ nếu bạn đang đối phó với các metaclass.

Lớp học: Bộ thực sự không phải là những gì bạn nghĩ nó là. Đó là một phạm vi kỳ lạ, và nó làm những điều kỳ lạ. Nó thực sự thậm chí không tạo ra một lớp học! Nó chỉ là một cách để thu thập một số biến - tên của lớp, các cơ sở, một chút từ điển của các thuộc tính và một metaclass.

Tên, từ điển và các cơ sở đều được chuyển đến hàm là metaclass, và sau đó nó được gán cho biến 'tên' trong phạm vi mà lớp: bộ: bộ.

Những gì bạn có thể đạt được bằng cách gây rối với các metaclass, và thực sự bằng các lớp học làm tổ trong các lớp tiêu chuẩn chứng khoán của bạn, khó đọc mã hơn, khó hiểu hơn về mã và các lỗi kỳ quặc khó hiểu mà không quen thuộc với lý do tại sao 'lớp' ' Phạm vi hoàn toàn khác với bất kỳ phạm vi Python nào khác.

Đã trả lời ngày 17 tháng 9 năm 2008 lúc 1:52Sep 17, 2008 at 1:52

JerubjerubJerub

40,9K15 Huy hiệu vàng72 Huy hiệu bạc90 Huy hiệu đồng15 gold badges72 silver badges90 bronze badges

2

Một trường hợp sử dụng tốt cho tính năng này là xử lý lỗi/ngoại lệ, ví dụ:

class DownloadManager(object):
    class DowndloadException(Exception):
        pass

    def download(self):
        ...

Bây giờ người đang đọc mã đã biết tất cả các ngoại lệ có thể liên quan đến lớp này.

Dù bằng cách nào, được xác định bên trong hoặc bên ngoài một lớp, sẽ hoạt động. Dưới đây là chương trình Lịch trình trả lương của nhân viên trong đó lớp trợ giúp mà Empinit được nhúng bên trong nhân viên lớp:

class   Employee:

    def level(self, j):
        return j * 5E3

    def __init__(self, name, deg, yrs):
        self.name = name
        self.deg = deg
        self.yrs = yrs
        self.empInit = Employee.EmpInit(self.deg, self.level)
        self.base = Employee.EmpInit(self.deg, self.level).pay

    def pay(self):
        if self.deg in self.base:
            return self.base[self.deg]() + self.level(self.yrs)
        print(f"Degree {self.deg} is not in the database {self.base.keys()}")
        return 0

    class   EmpInit:

        def __init__(self, deg, level):
            self.level = level
            self.j = deg
            self.pay = {1: self.t1, 2: self.t2, 3: self.t3}

        def t1(self):   return self.level(1*self.j)
        def t2(self):   return self.level(2*self.j)
        def t3(self):   return self.level(3*self.j)

if  __name__ == '__main__':
    for loop in range(10):
        lst = [item for item in input(f"Enter name, degree and years : ").split(' ')]
        e1 = Employee(lst[0], int(lst[1]), int(lst[2]))
        print(f'Employee {e1.name} with degree {e1.deg} and years {e1.yrs} is making {e1.pay()} dollars')
        print("EmpInit deg {0}\nlevel {1}\npay[deg]: {2}".format(e1.empInit.j, e1.empInit.level, e1.base[e1.empInit.j]))

Để xác định nó bên ngoài, chỉ cần empinit không suy nghĩ và thay đổi nhân viên. Tuy nhiên, vì nhân viên là bộ điều khiển của Empinit và người dùng không trực tiếp khởi tạo hoặc giao diện với nó, nên việc định nghĩa nó bên trong vì nó không phải là một lớp độc lập. Cũng lưu ý rằng Cấp độ Phương thức () được thiết kế để được gọi trong cả hai lớp ở đây. Do đó, nó cũng có thể được định nghĩa thuận tiện là một phương pháp tĩnh trong nhân viên để chúng tôi không cần phải chuyển nó vào empinit, thay vào đó chỉ cần gọi nó với nhân viên.level ().

Bạn có thể xác định một lớp trong lớp khác không?

Một lớp có thể được khai báo trong phạm vi của một lớp khác. Một lớp học như vậy được gọi là "lớp lồng nhau." Các lớp lồng nhau được coi là nằm trong phạm vi của lớp kèm theo và có sẵn để sử dụng trong phạm vi đó.. Such a class is called a "nested class." Nested classes are considered to be within the scope of the enclosing class and are available for use within that scope.

Python có hỗ trợ các lớp học lồng nhau không?

Các lớp bên trong (lồng nhau) trong Python là gì?Có lẽ bạn đã quen thuộc với lập trình hướng đối tượng và khái niệm về một lớp Python.Giống như bạn có thể tạo một hàm trong một hàm, trong Python, bạn có thể tạo một lớp bên trong một lớp.

Hai lớp có thể thừa hưởng từ Python khác không?

Trong Python, một lớp có thể kế thừa từ nhiều lớp.Nếu một lớp kế thừa, nó có các phương thức và biến từ các lớp cha.Về bản chất, nó được gọi là nhiều kế thừa vì một lớp có thể kế thừa từ nhiều lớp.Đây là một khái niệm từ lập trình định hướng đối tượng.a class can inherit from more than one class. If a class inherits, it has the methods and variables from the parent classes. In essence, it's called multiple inheritance because a class can inherit from multiple classes. This is a concept from object orientated programming.

Bạn có thể tạo một lớp học trong một lớp học?

Trong Java, có thể xác định một lớp trong một lớp khác, các lớp đó được gọi là các lớp lồng nhau.Chúng cho phép bạn nhóm các lớp nhóm hợp lý chỉ được sử dụng ở một nơi, do đó, điều này làm tăng việc sử dụng đóng gói và tạo ra mã dễ đọc và có thể duy trì hơn.it is possible to define a class within another class, such classes are known as nested classes. They enable you to logically group classes that are only used in one place, thus this increases the use of encapsulation, and creates more readable and maintainable code.