我有一个类Foo
,其中包含Bar
类型的数据库。我无法做出通用的“默认”Bar.__init__()
- 将Bar
对象传递给Foo.__init__()
方法。
如何告诉Python我想要这种类型的数据库?
class Foo:
# These are the other things I've tried, with their errors
myBar # NameError: name 'myBar' is not defined
Bar myBar # Java style: this is invalid Python syntax.
myBar = None #Assign "None", assign the real value in __init__. Doesn't work
#####
myBar = Bar(0,0,0) # Pass in "default" values.
def __init__(self, theBar):
self.myBar = theBar
def getBar(self):
return self.myBar
当我传入“默认”值时,这是有效的。但是,当我调用getBar
时,我不取回我在Foo.__init__()
函数中传入的那个 - 我得到“默认”值。
b = Bar(1,2,3)
f = Foo(b)
print f.getBar().a, f.getBar().b, f.getBar().c
这会吐出0 0 0
,不 1 2 3
,就像我期待的那样。
如果我不打算声明myBar
变量,我会在getBar(self):
方法(Foo instance has no attribute 'myBar'
)中出错。
在我的对象中使用自定义数据库的正确方法是什么?
答案 0 :(得分:7)
您无需告诉Python您将添加某个数据成员 - 只需添加它即可。 Python比例如动态更具动态性Java在这方面。
如果bar
个实例基本上是不可变的(意味着它们在实践中没有改变),您可以将默认实例作为__init__()
参数的默认值:
class Foo:
def __init__(self, the_bar=Bar(0,0,0)):
self.my_bar = the_bar
所有Foo
个实例默认值将共享一个Bar
实例。如果Bar
实例可能被更改,这可能不是你想要的,在这种情况下你应该使用这个习惯用法:
class Foo:
def __init__(self, the_bar=None):
if the_bar is None:
the_bar = Bar(0,0,0)
self.my_bar = the_bar
请注意,您通常不应该在Python中编写getter和setter。它们只是不必要的样板代码,会降低您的应用程序速度。由于Python支持属性,因此您也不需要它们可以面向未来。
答案 1 :(得分:2)
正确的方法是除了在构造函数中指定它之外什么都不做。
class Foo:
def __init__(self, bar):
self.bar = bar
def getbar(self):
return self.bar
答案 2 :(得分:2)
您绝对不必提前声明bar
。
听起来你希望Foo.bar
默认为一个值,如果没有指定,那么你可能会这样做:
class Foo:
def __init__(self, bar=None):
# one of many ways to construct a new
# default Bar if one isn't provided:
self._bar = bar if bar else Bar(...)
@property
def bar(self):
"""
This isn't necessary but you can provide proper getters and setters
if you prefer.
"""
return self._bar
@bar.setter
def bar(self, newbar):
"""
Example of defining a setter
"""
return self._bar = newbar
通常只是恰当地命名变量并省略setter被认为更加“pythonic”。
class Foo:
def __init__(self, bar=None):
self.bar = bar if bar else Bar(...)
答案 3 :(得分:1)
您不在Python中声明变量,并且变量是无类型的。
只是做:
class Foo(object):
def __init__(self, bar):
self.bar = bar
def getbar(self):
return self.bar
我怀疑这个问题是由你使用旧式类引起的,这种类很奇怪。如果你继承自object,你会得到一个新风格的类,它的设计不那么令人惊讶。