(类变量的使用)从java学来的python或讨厌的习惯?

2024-10-01 00:14:44 发布

您现在位置:Python中文网/ 问答频道 /正文

你好,Pythoneers:下面的代码只是我试图做的事情的一个模拟,但是它应该能说明我的问题。在

我想知道这是我从Java编程中学来的肮脏伎俩,还是一种有效的python方法:基本上我正在创建大量实例,但我需要在创建所有实例时跟踪它们的“静态”数据。在

class Myclass:
        counter=0
        last_value=None
        def __init__(self,name):
                self.name=name
                Myclass.counter+=1
                Myclass.last_value=name

以及使用这个简单类的一些输出,显示出一切都如我所预期的那样工作:

^{pr2}$

那么,这是一种普遍接受的做法,还是一种反模式?在

[例如,我不太高兴我显然可以从类内部(good)和外部(bad)设置计数器;也不希望从类代码本身内部使用完整的名称空间'Myclass'——只是看起来笨重而已;最后,我最初将值设置为“None”-可能我是在模仿静态类型语言?]在

我使用的是python2.6.2,程序是单线程的。在


Tags: 实例代码nameselfnonevalue编程counter
3条回答

您可以通过将代码拆分为两个独立的类来解决此问题。在

第一个类将用于您尝试创建的对象:

class MyClass(object):
    def __init__(self, name):
        self.Name = name

第二个类将创建对象并跟踪它们:

^{pr2}$

这样,您就可以根据需要创建类的新实例,但有关所创建类的信息仍然是正确的。在

>>> x = MyClassFactory.Build("Hello")
>>> MyClassFactory.Counter
1
>>> MyClassFactory.LastValue
'Hello'
>>> y = MyClassFactory.Build("Goodbye")
>>> MyClassFactory.Counter
2
>>> MyClassFactory.LastValue
'Goodbye'
>>> x.Name
'Hello'
>>> y.Name
'Goodbye'

最后,这种方法避免了实例变量隐藏类变量的问题,因为MyClass实例不知道创建它们的工厂。在

>>> x.Counter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'Counter'

去吧。不是。有。有状态的。班级。变量。在

调试是一个噩梦,因为类对象现在具有特殊功能。在

有状态类将两(2)个不相关的职责合并在一起:对象创建状态和创建的对象。不要把责任混为一谈,因为它们“似乎”属于一起。在本例中,创建对象的计数由工厂负责。被创造的对象有完全无关的责任(这不容易从问题中推断出来)。在

另外,请使用大写的类名。在

class MyClass( object ):
    def __init__(self, name):
            self.name=name

def myClassFactory( iterable ):
   for i, name in enumerate( iterable ):
       yield MyClass( name )

序列计数器现在是工厂的一部分,在这里状态和计数应该保持不变。在一个单独的工厂里。在

[对于玩代码高尔夫的人来说,这个时间更短。但这不是重点。关键是类不再是有状态的。]

从问题上来讲,Myclass实例是如何创建的还不清楚。由于缺乏任何线索,关于如何使用这家工厂,没有什么可说的了。罪魁祸首是不可饶恕的。可能是遍历列表、文件或其他iterable数据结构的东西。在

另外,对于刚从Java起步的人来说,factory对象只是一个函数。不需要更多了。在


因为这个问题的例子还不清楚,所以很难知道为什么(1)两个独特的对象是用(2)一个计数器创建的。这两个唯一的对象已经是两个唯一的对象,不需要计数器。在

例如,Myclass中的静态变量在任何地方都不会被引用。这使得我们很难理解这个例子。在

^{pr2}$

如果count或last value实际用于某物,那么可以创建一个可能有意义的示例。在

在我看来,类变量完全是python类型的。在

只要注意一件事。实例变量可以隐藏类变量:

x.counter = 5  # creates an instance variable in the object x.
print x.counter  # instance variable, prints 5
print y.counter  # class variable, prints 2
print myclass.counter # class variable, prints 2

相关问题 更多 >