简体   繁体   English

参数的python类继承

[英]python class inheritance for parameters

I am trying to create a schedule class in python that takes the start time, end time, and location of a meeting. 我正在尝试在python中创建一个计划类,该类需要开始时间,结束时间和会议的位置。 So far I have: 到目前为止,我有:

class Schedule(Time):
def __init__(self, start_time, end_time, location):
    self.start_time = start_time
    self.end_time = end_time
    self.location = location
    print (self.start_time)
    print (self.end_time)
    print (self.location)

I have a Time class completed which looks like this: 我完成了一个Time类,看起来像这样:

class Time():
    def __init__(self, init_hr = 12, init_min = 0, init_ampm = "AM"):
        self.hr = init_hr
        self.min = init_min
        self.ampm = init_ampm

Now I want to be able to make the parameters start_time and end_time (from the initialization of schedule) to be Time instances, however I'm confused on how I would go about doing that. 现在,我希望能够将参数start_time和end_time(从调度的初始化开始)设置为Time实例,但是我对如何执行此操作感到困惑。 Any suggestions? 有什么建议么?

You probably don't want Schedule to be a subclass of Time; 您可能不希望Schedule是Time的子类。 the relationship between the two is most likely "has a" rather than "is a". 两者之间的关系很可能是“具有”而不是“是”。 Just make it a subclass of object and you should be fine. 只要使其成为object的子类,就可以了。

You don't really need to change anything in your code. 您实际上不需要更改代码中的任何内容。

However, you can: 但是,您可以:

  • Document it to make it clear the expected type of the parameters (I recommend sphinx for that). 记录下来,以明确参数的预期类型(为此,我建议使用sphinx )。
  • Write assertions to make sure the type passed matches your expectations ( assert isinstance(variable, type) ). 编写断言以确保传递的类型符合您的期望( assert isinstance(variable, type) )。 You can even use some more advance libraries for that like pycontracts . 您甚至可以为pycontracts使用一些更高级的库。
  • Write unittests also to make sure that the whole API works as expected, that is, only the expected types are accepted ( unittest library works great, but you may want to take a look at alternative runners like nose or pytest ). 编写unittests还可以确保整个API都能按预期工作,也就是说,仅接受预期的类型( unittest库的效果很好,但是您可能要看一下鼻子pytest之类的替代运行器 )。

Regarding Schedule being a subclass of Time , I agree with the other answers. 关于ScheduleTime的子类,我同意其他答案。

Some dynamically-typed languages would want you to do this everywhere (statically-typed languages will generally enforce it themselves), but in Python the generally recommended practice is duck typing , which suggests that you just expect it to be a Time, but if it's something else, don't worry (if it implements the same interface as Time, well and good, if it doesn't, let it fail when you try accessing attributes that don't exist on the object). 某些动态类型的语言希望您在任何地方都可以执行此操作(静态类型的语言通常会自己执行),但是在Python中,通常建议的做法是鸭子类型 ,这表明您只是希望它是一个Time,但是如果它是别担心,别担心(如果它实现与Time相同的接口,那么很好,如果没有实现,则当您尝试访问对象上不存在的属性时让它失败)。 The general idea there is that you are expected to be intelligent enough to know what you're doing. 通常的想法是,您应该足够聪明,知道自己在做什么。

If a I were writing this code, I would leave it as you have it, with a few notes: 如果我正在编写此代码,请留意,并留有一些注意事项:

  • As others have mentioned, change class Schedule(Time) to class Schedule(object) . 如其他人所述,将class Schedule(Time)更改为class Schedule(object)
  • In Time.__init__ , don't call your parameters init_hr , etc., just call them hr , etc. Python ain't Java, where you've got to use different names or always refer to the class version as this.* . Time.__init__ ,不要调用参数init_hr等,而只将它们称为hr等。Python不是Java,在Java中您必须使用不同的名称或始终将类版本称为this.* In Python, you always use self.* . 在Python中,您始终使用self.* Python also has keyword arguments - so you could have Time(hr=4, ...) ; Python还具有关键字参数-因此您可以使用Time(hr=4, ...) ; Time(init_hr=4, ...) would be ugly. Time(init_hr=4, ...)很难看。
  • If you're in Python 2, change print (...) to print ... . 如果您使用的是Python 2,请将print (...)更改为print ... If you're in Python 3, change it to print(...) . 如果您使用的是Python 3,请将其更改为print(...)

Would you say that "a schedule is a time" ? 您会说“时间表就是时间”吗? I wouldn't. 我不会 This implies that they don't inherit in this way. 这意味着它们不会以这种方式继承。 I'd say that a schedule is a collection of times, which means that your schedule class will have an attribute which is a listing of times. 我想说时间表是时间的集合,这意味着您的时间表类将具有一个属性,该属性是时间列表。

Since in Python, type cannot be checked at compile time you need to write something like this on __init__ of Schedule 由于在Python中,无法在编译时检查类型,因此您需要在Schedule的__init__上编写类似的内容

if not isinstance(start_time, Time):
     raise ValueError("Start time need to be of type time")

or 要么

assert isinstance(start_time, Time)

Similarly for end_time also 同样对于end_time

Generally best practice in Python is to treat it as if it is a Time object and simply test whether it has the properties that you want rather than using isinstance . 通常,Python的最佳实践是将其视为Time对象,并简单地测试它是否具有所需的属性,而不是使用isinstance That way someone (including you) could create your own Time -like object in the future with the appropriate attributes ( hr , min , ampm ) and use it as a drop-in replacement. 这样,某个人(包括您)将来可以使用适当的属性( hrminampm )创建自己的类似Time的对象,并将其用作替代对象。 This would even work–if you aren't doing substantive logic with the Time objects or interact with that logic using operators–with their own custom objects that don't use the same fields. 如果您不对Time对象进行实质性逻辑处理,或者不使用运算符与该逻辑进行交互,那么使用自己的不使用相同字段的自定义对象甚至可以做到这一点。 That would have a few good advantages, depending on exactly how your schedule objects work. 这将具有一些良好的优势,具体取决于您的计划对象如何工作。

This style of coding is known as " Easier to ask for forgiveness than permission " and is relatively common in python, thanks to widespread use of duck typing . 这种编码风格被称为“ 比许可更容易请求宽恕 ”,并且由于广泛使用鸭子类型 ,在python中相对常见。

A somewhat better pattern than using isinstance that still lets you check whether it conforms to a standard (if you want to do that) might be to use hasattr instead. 比使用isinstance更好的模式(仍然允许您检查它是否符合标准)(如果要这样做)可能是使用hasattr For example: 例如:

hasattr(start_time, 'ampm')

I'll also agree with the others that a Schedule doesn't seem to have a is a relationship with Time but rather a has a relationship, else you could end up with someone creating a schedule with a Schedule as the start time and a Schedule as the end time. 我也将与其他同意, Schedule似乎并不具有关系Time而是关系,否则你可以用有人用创建时间表结束Schedule的开始时间和Schedule作为结束时间。

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

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