我可能来自不同的心态,主要是C++程序员.这个问题与Python中的OOP有关,更具体地说是纯虚方法.所以我从这个问题中改编代码,我正在研究这个基本样本.
class Animal():
def speak(self):
print("...")
class Cat(Animal):
def speak(self):
print("meow")
class Dog(Animal):
def speak(self):
print("woof")
my_pets = [Dog(), Cat(), Dog()]
for _pet in my_pets:
_pet.speak()
Run Code Online (Sandbox Code Playgroud)
所以你看到它为不同的派生类调用了speak函数.现在我的问题是鸭子打字都很好,我想我已经掌握了它.但是,在Python中追求更严格的OOP是不对的?所以我查看了抽象基类,特别是抽象方法.对我来说,这似乎是允许我用super调用基类方法.有没有任何方法/理由(在Python中)使speak()纯粹的实现一个派生的动物没有说话会抛出错误?
我对这种追求的论证是在编写你打算让人们进行子类化的模块和框架时,这会为他们自己记录他们需要实现这个功能的事实.一个非常糟糕的想法就是这样,让基类"纯"函数抛出异常.问题是在运行时发现了这个错误!
class VirtualException(BaseException):
def __init__(self, _type, _func):
BaseException(self)
class Animal():
def speak(self):
raise VirtualException()
class Cat(Animal):
def speak(self):
print("meow")
class Dog(Animal):
def speak(self):
print("woof")
class Wildebeest(Animal):
def function2(self):
print("What!")
my_pets = [Dog(), Cat(), Dog(), Wildebeest()]
for _pet in my_pets:
_pet.speak()
Run Code Online (Sandbox Code Playgroud) 我忙于一个项目,我必须在bash或ssh中自动化一些进程,所以我决定使用libexpect.so库.如果您不知道libexpect是什么,它提供了我可以在c ++程序中使用的expect扩展,并且期望只是一个程序,您可以在其中运行ssh等自动脚本.所以我可以执行一个尝试在某处ssh的脚本...当找到密码提示时,我可能已经预期会发送密码.
我的问题是,当我运行一个程序,即使是一个非常简单的程序时,我得到一个分段错误,我用gdb缩小到libexpect.so中的一个函数,名为exp_spawnv.
我知道我已经链接了库,它编译得很好,事实上当我在ubuntu中编译和运行时整个问题都不存在,但是在我的arch linux安装中,我得到了分段错误,我将在后面详述.我之所以在arch上构建它是因为我想最终使项目可以在大多数发行版上构建.
我的想法是,在我的arch安装中,有权限在调用exp_spawnv函数时失败,可能是管道,分支或其他任何东西.
为了证明我没有做一些时髦的事情,这里有一个简单的main.cpp用于说明目的.
#include <tcl8.5/expect.h>
int main()
{
FILE* file = exp_popen("bash");
}
Run Code Online (Sandbox Code Playgroud)
所以它只是有史以来最简单的期望计划.这是我编译和链接它.
$ g ++ -ggdb -c main.cpp
main.cpp:在函数'int main()'中:
main.cpp:5:32:警告:不推荐将字符串常量转换为'char*'[-Wwrite-strings]
$ g ++ main.o -lexpect -o mainprog
所以我得到了我的可执行程序mainprog ...只是运行会给我一个分段错误,没有别的.
如果我在gdb中运行mainprog它告诉我exp_spawnv中有一个seg错误.这是我在gdb中使用最后的回溯做的.
(gdb)运行
启动程序:/ home/user/testlibexpect/mainprog
警告:无法加载linux-vdso.so.1的共享库符号.
你需要"set solib-search-path"或"set sysroot"吗?
程序接收信号SIGSEGV,分段故障.
来自/usr/lib/libexpect.so的exp_spawnv()中的0x00007ffff7bc8836
(gdb)回溯
来自/usr/lib/libexpect.so的exp_spawnv()中的0 0x00007ffff7bc8836
来自/usr/lib/libexpect.so的exp_spawnl()中的1 0x00007ffff7bc8cb4
来自/usr/lib/libexpect.so的exp_popen()中的2 0x00007ffff7bc8d01
Main.cpp中的main()中的3 0x000000000040069:5
有两件事与我有关.
看看libexpect的联机帮助页,我知道exp_spawnv会分配一个新进程,我将能够通过FILE*进行通信.所以我想收到SIGSEGV信号因为叉子发生了什么不好的事情?
回溯中的那一行(警告:无法加载linux-vdso.so.1的共享库符号.)看起来很可疑?
总而言之,我的问题是我应该考虑什么来解决这个问题?我已经尝试从源代码构建expect库并通过arch包管理器pacman获取它......问题仍然存在,所以如果你知道我的意思,我认为库构建是不是很糟糕.
编辑:根据我所做的研究,我的顾虑点2不是问题,只是化妆品.
日食的反汇编如下:
00007ffff7bc87c6: mov 0x20c68b(%rip),%rax # 0x7ffff7dd4e58
00007ffff7bc87cd: mov (%rax),%rax
00007ffff7bc87d0: test %rax,%rax
00007ffff7bc87d3: je 0x7ffff7bc87d7 <exp_spawnv+935>
00007ffff7bc87d5: callq *%rax
00007ffff7bc87d7: …Run Code Online (Sandbox Code Playgroud)