我正在根据python3中的面向对象模型为我的公司开发一个相当复杂的应用程序.该应用程序包含几个包和子包,每个包当然包含一个__init__.py模块.
我主要使用那些__init__.py模块为它们内部的包声明泛型类,它们仅用作各自包的抽象模板.
我现在的问题是:这是一个使用__init__.py模块的"好"/"正确"/"pythonic"方式吗?或者我宁愿在其他地方声明我的泛型类?
举个例子,让我们假设一个包mypkg:
mypkg.__init__.py:
class Foo(object):
__some_attr = None
def __init__(self, some_attr):
self.__some_attr = some_attr
@property
def some_attr(self):
return self.__some_attr
@some_attr.setter
def some_attr(self, val):
self.__some_attr = val
Run Code Online (Sandbox Code Playgroud)
mypkg.myfoo.py:
from . import Foo
class MyFoo(Foo):
def __init__(self):
super().__init__("this is my implemented value")
def printme(self):
print(self.some_attr)
Run Code Online (Sandbox Code Playgroud) 我知道这里已经讨论过super()和多继承.但是我没有找到解决方案,关于我在python3中的具体问题.我们假设我们有:
#! /usr/bin/env python3
class A(object):
def __init__(self):
super().__init__()
def foo(self):
print("The")
class B(object):
def __init__(self):
super().__init__()
def foo(self):
print("world")
class C(B):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("is")
class D(A,C):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("nice")
d = D()
d.foo()
Run Code Online (Sandbox Code Playgroud)
这会让我:
The
nice
Run Code Online (Sandbox Code Playgroud)
另一方面,如果我将D()中的继承顺序更改为:
class D(C,A):
def __init__(self):
super().__init__()
def foo(self):
super().foo()
print("nice")
Run Code Online (Sandbox Code Playgroud)
它给了我
world
is
nice
Run Code Online (Sandbox Code Playgroud)
但是,我只获得所需的输出:
The
world
is
nice
Run Code Online (Sandbox Code Playgroud)
使用:
class D(C,A):
def __init__(self):
super().__init__()
def foo(self):
A.foo(self)
C.foo(self)
print("nice")
Run Code Online (Sandbox Code Playgroud)
我发现它非常不优雅.
所以我的问题是:是否可以在python3中使用super()来调用两个超类的超级方法而不仅仅是第一个?
我需要在python3中从没有后缀的文件中确定MIME类型,我认为python-magic是一个合适的解决方案.不幸的是它不能像这里描述的那样工作:https: //github.com/ahupp/python-magic/blob/master/README.md
这是怎么回事:
>>> import magic
>>> magic.from_file("testdata/test.pdf")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'from_file'
Run Code Online (Sandbox Code Playgroud)
所以我看了一下这个对象,它为我提供了Magic我在这里找到文档的类:http:
//filemagic.readthedocs.org/en/latest/guide.html
我很惊讶,这也不起作用:
>>> with magic.Magic() as m:
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'ms'
>>> m = magic.Magic()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() missing …Run Code Online (Sandbox Code Playgroud) 我有一堆想要链接的上下文管理器。乍一看,contextlib.nested看起来像是一个合适的解决方案。但是,此方法在文档中被标记为已弃用,该文档还指出最新with声明允许直接执行此操作:
2.7 版后已弃用: with 语句现在直接支持此功能(没有容易混淆的错误怪癖)。
但是我无法让 Python 3.4.3 使用上下文管理器的动态迭代:
class Foo():
def __enter__(self):
print('entering:', self.name)
return self
def __exit__(self, *_):
pass
def __init__(self, name):
self.name = name
foo = Foo('foo')
bar = Foo('bar')
Run Code Online (Sandbox Code Playgroud)
是否链式:
from itertools import chain
m = chain([foo], [bar])
with m:
pass
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: __exit__
m = [foo, bar]
Run Code Online (Sandbox Code Playgroud)
直接提供列表:
with m:
pass
Traceback (most recent call last):
File "<stdin>", line 1, in …Run Code Online (Sandbox Code Playgroud) 我有一些用例,我需要在不关心产生的项目的情况下运行生成器函数.
我不能使它们成为非齐型函数,因为在其他用例中我当然需要屈服值.
我目前正在使用一个简单的自制功能来耗尽发电机.
def exhaust(generator):
for _ in generator:
pass
Run Code Online (Sandbox Code Playgroud)
我想知道,是否有更简单的方法可以做到这一点,我错过了?
编辑 用例:
def create_tables(fail_silently=True):
"""Create the respective tables."""
for model in MODELS:
try:
model.create_table(fail_silently=fail_silently)
except Exception:
yield (False, model)
else:
yield (True, model)
Run Code Online (Sandbox Code Playgroud)
在某些情况下,我关心错误和成功价值......
for success, table in create_tables():
if success:
print('Creation of table {} succeeded.'.format(table))
else:
print('Creation of table {} failed.'.format(table), file=stderr)
Run Code Online (Sandbox Code Playgroud)
...而在某些我只是想"盲目地"运行这个功能:
exhaust(create_tables())
Run Code Online (Sandbox Code Playgroud) 我可以使用这个特殊的转义序列在 bash 中打印超链接:
echo -e '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'
Run Code Online (Sandbox Code Playgroud)
结果(我可以点击链接):
This is a link
Run Code Online (Sandbox Code Playgroud)
现在我想在 Python 3.10 中生成这个:
print('\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n')
\e]8;;http://example.com\e\This is a link\e]8;;\e\
print(r'\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n')
\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,shell 不解释转义序列。其他转义序列(例如粗体文本的转义序列)也可以:
print('\033[1mYOUR_STRING\033[0m')
YOUR_STRING # <- is actually bold
Run Code Online (Sandbox Code Playgroud)
如何让 python 正确格式化 URL?
我正在使用 python3 中的 peewee为现有数据库构建 ORM 。
现在我在一张表中面临问题,即有一列名为import,我必须将其作为类的属性引入。这当然没有那么简单,因为它是 python 语言中的关键字。有没有办法以另一种方式更改字段的名称?我无法更改列的名称,因为它会在其他系统上产生大量副作用。
我没有成功尝试获取magic with-statement方法__enter__并__exit__在类级别上运行:
class Spam():
@classmethod
def __enter__(cls):
return cls
@classmethod
def __exit__(cls, typ, value, tb):
cls.cleanup_stuff()
with Spam:
pass
Run Code Online (Sandbox Code Playgroud)
但是,这将导致AttributeError:
Traceback (most recent call last):
File "./test.py", line 15, in <module>
with Spam:
AttributeError: __exit__
Run Code Online (Sandbox Code Playgroud)
是否可以在类级别使用__enter__和__exit__方法?
我有以下用于配置实现的抽象基类(简短):
class Config():
"""
Configuration file binding
"""
def __init__(self, path):
"""
Initialize the config file
"""
path = path if path.endswith(self.__SUFFIX) else path + self.__SUFFIX
self.__file = ConfigFile(path)
self.__defaults = self.dict()
@property
def fields(self):
"""
Returns a list of fields
"""
return [field for field in self.dict()]
def dict(self):
"""
Determine existing fields
"""
return {field:getattr(self, field)
for field in dir(self)
if field.upper() == field
and not field.startswith('_')}
def reset(self):
"""
Reset the file to the default values
""" …Run Code Online (Sandbox Code Playgroud) 我有类,使用相同的getter共享相同的属性,但是不同的setter.作为一个简单,无用的例子,类似于:
class Spam():
@property
def foo(self):
return self.bar
@foo.setter
def foo(self, foo):
self.bar = foo
class Eggs(Spam):
@foo.setter
def foo(self, foo):
self.bar = ' '.join(['Egg\'s foo:', foo])
Run Code Online (Sandbox Code Playgroud)
但是,尝试运行此模块会引发以下错误:
Traceback (most recent call last):
File "./test.py", line 13, in <module>
class Eggs(Spam):
File "./test.py", line 14, in Eggs
@foo.setter
NameError: name 'foo' is not defined
Run Code Online (Sandbox Code Playgroud)
为了使这项工作符合要求,我需要重新定义Eggs.foo:
class Eggs(Spam):
@property
def foo(self):
return super().foo
@foo.setter
def foo(self, foo):
self.bar = ' '.join(['Egg\'s foo:', foo])
Run Code Online (Sandbox Code Playgroud)
有没有办法避免重新定义属性?因为如果你像我这样在几个子类中有很多这样的getter和setter,这非常烦人.
python ×9
python-3.x ×8
inheritance ×2
attributes ×1
chain ×1
class-method ×1
declaration ×1
generator ×1
hyperlink ×1
iterable ×1
keyword ×1
peewee ×1
properties ×1
python-magic ×1
super ×1
superclass ×1