简体   繁体   English

扩展 class 而不访问其 __init__ 方法

[英]Extend a class without access to its __init__ method

I am trying to extend a class from a given library but I do not have access to the __init__ of the class, only to a function generating an instance.我正在尝试从给定库扩展 class,但我无权访问 class 的__init__ ,只能访问生成实例的 function。 Something like就像是

class A:
    pass


def return_an_A():
    return A()


class B(A):
    # How to instantiate B with only access to return_an_A
    def extend_A():
        pass

How can I define the instanciation of class B?如何定义 class B 的实例化?

Thanks for your help.谢谢你的帮助。

Update更新

As rightfully noticed, my example was poorly set up so here is, I hope, a better explanation of my real issue.正如正确地注意到的那样,我的示例设置不当,所以我希望这里可以更好地解释我的实际问题。

The original code I used was the following.我使用的原始代码如下。

import gitlab


# Here gl.projects.get(project_name) is an instance of the class
# gitlab.v4.objects.Project
def project(url, private_token, project_name):
    with gitlab.Gitlab(url, private_token) as gl:
        return gl.projects.get(project_name)

# This implementation takes an instance of gitlab.v4.objects.Project
def list_files(project, commit_branch):
    current_files = []
    if not project.empty_repo:
        current_files = [
            f["path"]
            for f in project.repository_tree(
                ref=commit_branch
            )
        ]

    return current_files

I wanted to have a structure like我想要一个像这样的结构

class MyProject:

    # Here is missing the way to instantiate like the project function
    # I don't want to pass a Project instance as a parameter to make it an
    # attribute, I would like to extend the class Project itself

    def list_files(self, commit_branch):
        current_files = []
        
        # Note here that the variables of the 
        # gitlab.v4.objects.Project are directly accessible
        if not self.empty_repo:
            current_files = [
                f["path"]
                for f in self.repository_tree(
                    ref=commit_branch
                )
            ]

        return current_files   

but I can't manage to find the right way to write the __init__ .但我无法找到编写__init__的正确方法。

I found a solution to my issue by using a delegation pattern.我通过使用委托模式找到了解决我的问题的方法。

class Project:

    def __init__(self, private_token, project_name, url):
        self.private_token = private_token
        self.project_name = project_name
        self.url = url

    # Delegate all methods and properties to the child class when those are not found
    # in the class
    def __getattr__(self, attr):
        return self._project.__getattribute__(attr)

    @property
    def _project(self):
        with gitlab.Gitlab(self.url, self.private_token) as gl:
            return gl.projects.get(self.project_name)

    def list_files(self, branch):
        current_files = []
        if not self._project.empty_repo:
            current_files = [
                f["path"]
                for f in self._project.repository_tree(
                    ref=branch, recursive=True, all=True
                )
                if f["type"] == "blob"
            ]

        return current_files

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM