使用Python类进行封装,而不是实例化

时间:2017-11-21 07:53:13

标签: python class inheritance

我遇到了一些Python代码示例,如下所示:

class GiveNext :

    list = ''

    def __init__(self, list) :
        GiveNext.list = list

    def giveNext(self, i) :
        retval = GiveNext.list[i]
        return retval



class GiveABCs(GiveNext):

    i = -1

    def _init__(self, list) :
        GiveNext.__init__(self, list)

    def giveNext(self):
        GiveABCs.i += 1
        return GiveNext.giveNext(self, GiveABCs.i)


class Give123s(GiveNext):

    i = -1

    def _init__(self, list) :
        GiveNext.__init__(self, list)

    def giveNext(self):
        Give123s.i += 1
        return GiveNext.giveNext(self, Give123s.i)


for i in range(3):
    print(GiveABCs('ABCDEFG').giveNext())
    print(Give123s('12345').giveNext())

输出为:A 1 B 2 C 3

如果我更聪明,我可以弄清楚如何将字符串文字放在构造函数中......但这现在并不重要。

我的问题是以这种方式使用类。是的,每次打印print()中的调用时都会创建类的实例。然而,我在每个班级都是“永久的”。

这让我感觉不像是面向对象的方法,更多的是使用类来完成封装和/或函数式编程范例的方法,因为实例完全是暂时的。换句话说,类的实例永远不会为了自己的目的而实例化;它只是允许访问类中的方法和变量来做他们的事情,然后它被抛弃。在许多情况下,似乎是以反手方式使用类机制,以便利用继承和名称解析/间隔:从概念上讲,实际上从不需要构建或使用类的实例。

这是标准的Python表单吗?

奖金问题:我如何将字符串文字放在每个类声明中?现在,即使我将GiveABCs的_init__更改为

GiveNext.__init__(self, 'wxyz')

它完全忽略了'wxyz'文字,并使用'ABCDEF'文字 - 即使它从未被提及过......

2 个答案:

答案 0 :(得分:1)

OP中的这段代码是一堆令人难以置信的垃圾。它不仅长,不可读,滥用OO功能,并且根本不使用Python功能(迭代器是标准的Python功能)。以下是更多Python主义方法的建议:

giveABCs = iter('ABCDEFG')
give123s = iter('12345')
for i in range(3):
    print(next(giveABCs))
    print(next(give123s))

关于你的红利问题:我猜你正在修改GiveABCs和Give123s的_init__()方法。你输入的代码没有任何效果是正常的,因为Python构造函数是__init__()(带有2个前导下划线,而不是1)。所以来自GiveNext的构造函数没有重载。

答案 1 :(得分:1)

请不要使用此代码学习Python。正如其他人所说,这段代码违反了许多Python原则。

一个例子:list是Python内置类型。不要覆盖它,特别是不要使用字符串实例!

代码还混合了类和实例变量,并没有在子类中使用super()

此代码尝试模拟迭代器。所以只需使用iterator

give_abcs = iter('ABCDEFG')
give_123s = iter('12345')

for _ in range(3):
    print(next(give_abcs))
    print(next(give_123s))

# A
# 1
# B
# 2
# C
# 3

如果您确实要修复上述代码,可以使用:

class GiveNext :
    def __init__(self, iterable) :
        self.i = - 1
        self.iterable = iterable

    def giveNext(self) :
        self.i += 1
        return self.iterable[self.i]

giveABCs = GiveNext('ABCDEFG')
give123s = GiveNext('12345')

for _ in range(3):
    print(giveABCs.giveNext())
    print(give123s.giveNext())

输出:

A
1
B
2
C
3