相关疑难解决方法(0)

使用多重继承调用父类__init__,这是正确的方法吗?

假设我有一个多继承场景:

class A(object):
    # code for A here

class B(object):
    # code for B here

class C(A, B):
    def __init__(self):
        # What's the right code to write here to ensure 
        # A.__init__ and B.__init__ get called?
Run Code Online (Sandbox Code Playgroud)

有写作两种典型的方法C__init__:

  1. (老式) ParentClass.__init__(self)
  2. (新样式) super(DerivedClass, self).__init__()

但是,在任何一种情况下,如果父类(AB)不遵循相同的约定,则代码将无法正常工作(某些可能会被遗漏,或被多次调用).

那么又是什么样的正确方法呢?很容易说"只是保持一致,遵循一个或另一个",但如果AB来自第三方图书馆,那么呢?有没有一种方法可以确保所有父类构造函数被调用(并且以正确的顺序,只有一次)?

编辑:看看我的意思,如果我这样做:

class A(object):
    def __init__(self):
        print("Entering A")
        super(A, self).__init__()
        print("Leaving A")

class B(object):
    def __init__(self):
        print("Entering B")
        super(B, self).__init__()
        print("Leaving B")

class …
Run Code Online (Sandbox Code Playgroud)

python oop inheritance multiple-inheritance super

138
推荐指数
4
解决办法
6万
查看次数

__lt__而不是__cmp__

Python 2.x有两种方法可以重载比较运算符,__cmp__或者"丰富的比较运算符",如__lt__. 丰富的比较超载被认为是首选,但为什么会这样呢?

丰富的比较运算符更容易实现每个,但您必须使用几乎相同的逻辑实现其中几个.但是,如果你可以使用内置cmp和元组排序,那么__cmp__变得非常简单并完成所有的比较:

class A(object):
  def __init__(self, name, age, other):
    self.name = name
    self.age = age
    self.other = other
  def __cmp__(self, other):
    assert isinstance(other, A) # assumption for this example
    return cmp((self.name, self.age, self.other),
               (other.name, other.age, other.other))
Run Code Online (Sandbox Code Playgroud)

这种简单性似乎比重载所有6(!)丰富的比较更好地满足了我的需求.(但是,如果你依赖于"交换的论证"/反映的行为,你可以把它归结为"只是"4,但这导致并发症的净增加,在我的拙见中.)

如果我只是超载,是否有任何不可预见的陷阱需要注意__cmp__

我明白了<,<=,==等运营商也可以被重载用于其他目的,并且可以返回任何他们喜欢的对象.我不是在询问这种方法的优点,而是仅仅考虑使用这些运算符进行比较时的差异,这与它们对数字的意义相同.

更新:克里斯托弗指出,cmp正在消失3.x. 有没有其他方法可以使实施比较变得如上所述__cmp__

python operator-overloading

96
推荐指数
3
解决办法
5万
查看次数

Django Model Mixins:继承自models.Model还是来自对象?

这是一个关于Python Mixins的问题,一般来说可能很有用.我只是使用Django模型,因为这是我最熟悉的用例.

如果mixin继承自该类,它是否设计为与'object'混合使用?

代码示例,更正确或更好,或更好,取决于您想要实现的目标?

这个

class TaggingMixin(models.Model):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

或这个:

class TaggingMixin(object):
    tag = models.ForeignKey(Tag)

    class Meta:
        abstract = True

class MyModel(models.Model, TaggingMixin):
    title = models.CharField(max_length=100)
Run Code Online (Sandbox Code Playgroud)

我认为从对象继承是正确的方法.但我正在网上看到第一个案例的例子......

编辑:我已将我的后续问题转移到一个单独的问题:Django抽象模型与简单Python混合与Python ABCs

python

67
推荐指数
3
解决办法
2万
查看次数

是否可以在Enum中定义类常量?

Python 3.4引入了一个新模块enum,它为该语言添加了枚举类型.该文档enum.Enum提供了一个示例来演示如何扩展它:

>>> class Planet(Enum):
...     MERCURY = (3.303e+23, 2.4397e6)
...     VENUS   = (4.869e+24, 6.0518e6)
...     EARTH   = (5.976e+24, 6.37814e6)
...     MARS    = (6.421e+23, 3.3972e6)
...     JUPITER = (1.9e+27,   7.1492e7)
...     SATURN  = (5.688e+26, 6.0268e7)
...     URANUS  = (8.686e+25, 2.5559e7)
...     NEPTUNE = (1.024e+26, 2.4746e7)
...     def __init__(self, mass, radius):
...         self.mass = mass       # in kilograms
...         self.radius = radius   # in meters
...     @property
...     def surface_gravity(self):
...         # universal …
Run Code Online (Sandbox Code Playgroud)

python enums constants class-constants python-3.x

50
推荐指数
4
解决办法
8767
查看次数

将基类转换为派生类python(或更多pythonic方式的扩展类)

我需要扩展Networkx python包并Graph为我的特殊需要添加一些方法

我想这样做的方法是简单地推导出一个新类说NewGraph,并添加所需的方法.

然而,networkx中还有一些其他函数可以创建和返回Graph对象(例如,生成随机图).我现在需要将这些Graph对象转换为NewGraph对象,以便我可以使用我的新方法.

这样做的最佳方式是什么?或者我应该以完全不同的方式解决问题?

python inheritance base-class derived-class

38
推荐指数
2
解决办法
3万
查看次数

接口+扩展(mixin)与基类

接口+扩展方法(mixin)是否优于抽象类?

如果你的答案是"它取决于",它依赖于什么?

我看到接口+扩展方法有两个可能的优点.

  • 接口是多重可继承的,而类则不是.
  • 您可以使用扩展方法以不间断的方式扩展接口.(实现您的界面的客户端将获得新的基本实现,但仍然可以覆盖它.)

我还没有想到这种方法的缺点.接口+扩展方法失败可能有一个明显的简单原因.

关于这个主题的两篇有用的文章是

.net extension-methods abstract-class interface

29
推荐指数
2
解决办法
3690
查看次数

Python使用其他类的方法

如果我有两个类,并且其中一个类具有我想在其他类中使用的函数,那么我使用什么以便我不必重写我的函数?

python methods class

29
推荐指数
3
解决办法
5万
查看次数

来自两个派生类的多重继承

我有一个抽象的基类作为接口.

我有两个派生类的"集合",它们实现了抽象类的一半.(一个"set"定义与初始化相关的抽象虚拟方法,另一个"set"定义与实际"工作"相关的那些.)

然后,我得到了使用多继承来构造完全定义的类的派生类(并且本身不添加任何东西).

所以:(坏伪代码)

class AbsBase {
  virtual void init() = 0;
  virtual void work() = 0;
}

class AbsInit : public AbsBase {
  void init() { do_this(); }
  // work() still abs
}

class AbsWork : public AbsBase {
  void work() { do_this(); }
  // init() still abs
}

class NotAbsTotal : public AbsInit, public AbsWork {
  // Nothing, both should be defined
}
Run Code Online (Sandbox Code Playgroud)

首先,我可以这样做吗?我可以继承两个派生自同一Base的类吗?(希望如此).

虽然这是"真正的问题"(我在上面撒谎以简化示例).

我真正做的是将非抽象访问器方法添加到基类:

class AbsBase {
public:
  void init() { init_impl(); }
  void work() { …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance multiple-inheritance

26
推荐指数
1
解决办法
6万
查看次数

最简洁的方法来禁用复制和移动语义

以下肯定有效,但非常繁琐:

T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
Run Code Online (Sandbox Code Playgroud)

我正试图发现最简洁的方式.以下工作会吗?

T& operator=(T) = delete;
Run Code Online (Sandbox Code Playgroud)

更新

请注意,我选择T& operator=(T)而不是T& operator=(const T&)T& operator=(T&&),因为它可以同时满足两个目的.

c++ copy move-semantics c++11

17
推荐指数
3
解决办法
2944
查看次数

sklearn中的transformer和estimator有什么区别?

我看到sklearn 文档中提到了Transformerestimator

这两个词有什么区别吗?

scikit-learn

14
推荐指数
1
解决办法
2645
查看次数