在集成我之前没有使用的Django应用程序时,我发现了两种不同的方法来定义类中的函数.作者似乎非常故意地使用它们.第一个是我自己经常使用的一个:
class Dummy(object):
def some_function(self,*args,**kwargs):
do something here
self is the class instance
Run Code Online (Sandbox Code Playgroud)
另一个是我不使用的,主要是因为我不明白何时使用它,以及为什么:
class Dummy(object):
@classmethod
def some_function(cls,*args,**kwargs):
do something here
cls refers to what?
Run Code Online (Sandbox Code Playgroud)
在Python文档中,classmethod
装饰器用这句话解释:
类方法接收类作为隐式的第一个参数,就像实例方法接收实例一样.
所以我猜cls
是指Dummy
自己(class
不是实例).我不完全理解为什么会这样,因为我总能做到这一点:
type(self).do_something_with_the_class
Run Code Online (Sandbox Code Playgroud)
这只是为了清楚起见,还是我错过了最重要的部分:如果没有它,那些怪异而迷人的东西是无法完成的?
python language-details method-dispatch class-method language-lawyer
我在glibc中看到了debug printfs (void) 0
,如果定义了NDEBUG,则内部定义为.同样__noop
,Visual C++编译器也是如此.前者适用于GCC和VC++编译器,而后者仅适用于VC++.现在我们都知道上述两个语句都将被视为无操作,并且不会生成相应的代码; 但这是我怀疑的地方.
在这种情况下__noop
,MSDN说它是编译器提供的内部函数.来(void) 0
〜为什么编译器将其解释为没有操作?这是C语言的一个棘手的用法还是标准说明了它的明确性?或者甚至那与编译器实现有关?
我正在阅读C++编程语言,其中Stroustrup声明char的int值可以在0到255或-127到127之间,具体取决于实现.它是否正确?它似乎应该是从-128到127.如果不是,为什么在第二种实现可能性中它们只有255个可能的值,而不是256.
我有一个方法,它采用一个生成器加上一些额外的参数,并产生一个新的生成器:
function merge(\Generator $carry, array $additional)
{
foreach ( $carry as $item ) {
yield $item;
}
foreach ( $additional as $item ) {
yield $item;
}
}
Run Code Online (Sandbox Code Playgroud)
此函数的常用用例与此类似:
function source()
{
for ( $i = 0; $i < 3; $i++ ) {
yield $i;
}
}
foreach ( merge(source(), [4, 5]) as $item ) {
var_dump($item);
}
Run Code Online (Sandbox Code Playgroud)
但问题是有时我需要将空源传递给merge
方法.理想情况下,我希望能够做到这样的事情:
merge(\Generator::getEmpty(), [4, 5]);
Run Code Online (Sandbox Code Playgroud)
这正是我在C#中所做的事情(有一个IEnumerable<T>.Empty
属性).但我手册中没有看到任何类型的empty
发电机.
我已经设法使用此函数解决此问题(现在):
function sourceEmpty()
{
if ( false ) { …
Run Code Online (Sandbox Code Playgroud) 简而言之,这不会编译:
public <A> void test() {
A[] temp = new A[]{};
}
Run Code Online (Sandbox Code Playgroud)
是因为向后兼容性问题,还是语言设计中的一些根本兼容性呢?
这基本上是关于临时生命的问题.如果函数返回一个对象,但该引用未分配给变量并且仅用于调用返回对象上的方法,则临时引用是否会自动清除?
举一个具体的例子,假设有一系列方法调用:
o.method_a().method_b()
Run Code Online (Sandbox Code Playgroud)
o.method_a()
当调用method_b()
完成时,自动清除返回的临时引用,就好像该行写成:
tmp = o.method_a()
try:
tmp.method_b()
finally:
tmp = None
Run Code Online (Sandbox Code Playgroud)
编辑:我对一般答案感兴趣.一旦引用计数降至0,CPython就会终止对象.其他Python实现可能不会立即终止对象.我想知道Python语言是否像C++一样,它保证临时对象在创建它们的语句的末尾被销毁.(除了在Python中,问题是临时引用是否在创建它们的语句的末尾被清除.)
在C++中,类似的代码可能用以下方法实现:
class B {
public:
void method_b();
};
class A {
public:
std::shared_ptr<B> method_a();
};
A o;
o.method_a()->method_b();
Run Code Online (Sandbox Code Playgroud)
C++标准规定"临时对象被破坏作为评估全表达式的最后一步......(词法上)包含创建它们的点.即使该评估以抛出异常结束,也是如此." 在此示例中,这意味着在完全表达式的求值结束时,将立即销毁std::shared_ptr<B>
由调用创建的临时对象.销毁a 意味着清除对共享对象的引用.A::method_a()
o.method_a()->method_b();
std::shared_ptr
不过,我仍然坚持注释; 相关规则是:
Annotation:
@ QualifiedIdentifier [ ( [AnnotationElement] ) ]
AnnotationTypeDeclaration:
@ interface Identifier AnnotationTypeBody
Run Code Online (Sandbox Code Playgroud)
但我没有看到@
词汇规范中任何地方提到的符号.标记化的正确规则是什么@
,或者我在哪里可以找到这样的规则?
我意识到我可以轻松地为此添加一个令牌定义,它甚至可能有效.但是如果可能的话,我希望根据规范正确地做到这一点.