下面是我的用例:我想定义一个类似元组的对象,但是我可以通过属性名访问它的元素,例如
mytupleobj = TupObj(2012,3)
mytupleobj.year = 2012
mytupleobj.month = 3
Pythonsnamedtuple
是这方面的首选,但问题是参数的数量是固定的。因此,如果只需要有带年份的tuple类对象,我要么就必须安装
mytupleobj = TupObj(2012, None)
或者创建一个只携带年份的名称元组的新定义。两种解决方案看起来都不怎么样。
有没有一种方法——使用< code>namedtuple或其他技术——当我实例化
mytupleobj = TupObj(2012)
我得到一个类似元组的对象实例化,它只有属性年份
,当我使用时
mytupleobj = TupObj(2012,2)
我得到一个具有年
和月
属性的类似元组的对象?
您可以在namedtuple
上设置默认值
Python 2.7解决方案:
from collections import namedtuple
tupobj = namedtuple('tupobj', 'year month')
tupobj.__new__.__defaults__ = (None,) * len(tupobj._fields)
t1 = tupobj(2012)
print(t1)
# >> tupobj(year=2012, month=None)
print(t1.year)
# >> 2012
t2 = tupobj(year=2012)
print(t2)
# >> tupobj(year=2012, month=None)
print(t2.year)
# >> 2012
t3 = tupobj(month=1)
print(t3)
# >> tupobj(year=None, month=1)
print(t3.month)
# >> 1
t4 = tupobj(2012, 1)
print(t4)
# >> tupobj(year=2012, month=1)
print(t4.year)
# >> 2012
print(t4.month)
# >> 1
Python 3.7解决方案:
from collections import namedtuple
tupobj = namedtuple('tupobj', 'year month', defaults=(None,None))
t1 = tupobj(2012)
print(t1)
# >> tupobj(year=2012, month=None)
print(t1.year)
# >> 2012
t2 = tupobj(year=2012)
print(t2)
# >> tupobj(year=2012, month=None)
print(t2.year)
# >> 2012
t3 = tupobj(month=1)
print(t3)
# >> tupobj(year=None, month=1)
print(t3.month)
# >> 1
t4 = tupobj(2012, 1)
print(t4)
# >> tupobj(year=2012, month=1)
print(t4.year)
# >> 2012
print(t4.month)
# >> 1
如果您的目标是从OOP的角度理解实现,那么您只需要处理条件并传递值的默认参数,在初始化期间检查它们的条件值。它可能看起来像这样:
class mydatetimeclass():
def __init__(self, year, month=None, day=None):
self.year = year
if month is not None:
self.month = month
if day is not None:
self.day = day
obj1 = mydatetimeclass(2016)
obj1.year #2016
obj2 = mydatetimeclass(2017, 5)
obj2.year #2017
obj2.month #5
另一种更干净的实现/维护方法是将默认值保存为None,这样您就不必担心每个对象中实际存在哪些属性。
class mydatetimeclass():
def __init__(self, year, month=None, day=None):
self.year = year
self.month = month #sets to None by default
self.day = day
您不希望有不同的类定义。如果没有传入一个< code>month值,您只需要用属性的默认值使这些参数成为可选的。< code>namedtuple()工厂函数不支持该用例。
但这并不是创建命名元组的唯一方法。您还可以将类型划分为子类。NamedTuple
:
from typing import NamedTuple, Optional
class VagueTimePeriod(NamedTuple):
year: int
month: Optional[int] = None
这是命名元组的类定义,其中 month
是可选的,如果未指定月份,则将其保留为默认值:
>>> VagueTimePeriod(2012)
VagueTimePeriod(year=2012, month=None)
>>> VagueTimePeriod(2012, 3)
VagueTimePeriod(year=2012, month=3)
然而,我怀疑你真正想要的是一个数据类。一个简单的类,主要只是保存一些数据。
Python 3.7具有新的dataclass
模块,或者您可以安装attrs
项目。数据类可以具有可选属性(默认为您在定义时声明的值):
from dataclasses import dataclass
from typing import Optional
@dataclass
class VagueTimePeriod:
year: int
month: Optional[int] = None
vtp1 = VagueTimePeriod(2012)
vtp2 = VagueTimePeriod(2012, 3)
数据类为您提供了大大简化的语法来定义一个小类,该类具有表示、相等性测试以及可选的排序支持、哈希和不变性。
数据类还完全支持继承,而命名元组不支持继承。
数据类不是自动可迭代或不可变的,但可以做到这一点,请参阅我前面的回答,其中我定义了一个简单的添加序列行为的DataclassSequence
基类。
快速演示:
>>> @dataclass(frozen=True)
... class VagueTimePeriod:
... year: int
... month: Optional[int] = None
...
>>> VagueTimePeriod(2012)
VagueTimePeriod(year=2012, month=None)
VagueTimePeriod(2012, 3)
VagueTimePeriod(year=2012, month=3)
在问我的问题之前,我想把一些事情说清楚。首先,我是Java和编程的新手。第二,这是我的第一个帖子,所以如果我做错了什么,请宽容对待我。最后,我不想要任何具体的解决办法,我的任务在任何回应这篇文章。这些问题要我来解决。我想要的是一个解释,为什么我的测试代码不能编译/运行。为了更好地理解这个问题,我将粘贴赋值信息,然后是给定的驱动程序类,然后是驱动程序类访问的我的类代码。我的编译器错误显示在标题中,但
我有一个抽象的超类,它有一个形式的构造函数 并希望创建该抽象类的一个子类,该子类不是以字符串作为其第一个参数,而是采用一个表示给定字符串名称的整数值,例如,0代表某个字符串,1代表另一个字符串,依此类推。 当我尝试编写窗体子类(int number,int amount)的构造函数时,我得到一个格式为“Implicit super constructor is undefined.必须显式调用另一
问题内容: 如何使AB的构造函数使用适当的参数调用A和B的构造函数? 我试过了 但这给我一个错误。 问题答案: 你没有通过。 请注意,如果这种继承层次结构变得更加复杂,则会遇到构造函数无法执行或无法重新执行的问题。外观到(和问题与),并从不要忘记继承如果你在2.x和你的类不从别的继承。
我想问一下java编程语言,具体到构造函数。假设我们有一个类测试,在那里我们测试整个程序,和类点,在那里定义构造函数(集和获取方法btw)。类行: 类点: 现在,如果我在构造函数中输入类点的名称,那将是一个错误:
我得到了下面的代码,使用数组来查找一些prim数。然而,当试图编译我的用户类PalindromeArrayUser时,它说——“类中的构造函数不能应用于给定的类型” 要求:int。找到:没有论点。原因:实际参数和正式参数列表的长度不同。 但是,我已经向构造器传递了一个int值(与我的蓝图中设计的方式相同)。我不太明白问题来自哪里。谢谢。 这是我的两节课 而这就是我的用户类问题的来源。上面的类编译良
在Dart中,工厂构造函数需要编码器提供更多逻辑,但与常量构造函数没有太大区别,只是它们允许“非最终”实例变量。 与const Constructor相比,它们有哪些优点? 谢谢大家。 编辑 下面是关于Seth Ladd博客“Dart-试图理解“工厂”构造函数的价值”中工厂构造函数的用法。 恕我直言,使用通用构造函数,可以通过细微的差异实现相同的效果,但相当简单。 如上所示,尽管这两个实例 所以,