Foo = Class.new
Foo.class_eval do
def class_bar
"class_bar"
end
end
Foo.instance_eval do
def instance_bar
"instance_bar"
end
end
Foo.class_bar #=> undefined method ‘class_bar’ for Foo:Class
Foo.new.class_bar #=> "class_bar"
Foo.instance_bar #=> "instance_bar"
Foo.new.instance_bar #=> undefined method ‘instance_bar’ for #<Foo:0x7dce8>
Run Code Online (Sandbox Code Playgroud)
只是基于方法的名称,我希望class_eval允许你向Foo和instance_eval添加一个类方法,以允许你向Foo添加一个实例方法.但他们似乎反其道而行之.
在上面的例子中,如果你在Foo类上调用class_bar,你会得到一个未定义的方法错误,如果你在Foo.new返回的实例上调用instance_bar,你也会得到一个未定义的方法错误.这两个错误似乎都与对class_eval和instance_eval应该做什么的直观理解相矛盾.
这些方法之间有什么区别?
class_eval的文档:
mod.class_eval(string [,filename [,lineno]])=> obj
在mod的上下文中计算字符串或块.这可以用于向类添加方法.
obj.instance_eval {| | block} => obj
在接收器(obj)的上下文中计算包含Ruby源代码或给定块的字符串.为了设置上下文,在代码执行时将变量self设置为obj,使代码可以访问obj的实例变量.
Python 3.4 增加了使用静态方法定义函数重载的功能.这基本上是文档中的示例:
from functools import singledispatch
class TestClass(object):
@singledispatch
def test_method(arg, verbose=False):
if verbose:
print("Let me just say,", end=" ")
print(arg)
@test_method.register(int)
def _(arg):
print("Strength in numbers, eh?", end=" ")
print(arg)
@test_method.register(list)
def _(arg):
print("Enumerate this:")
for i, elem in enumerate(arg):
print(i, elem)
if __name__ == '__main__':
TestClass.test_method(55555)
TestClass.test_method([33, 22, 11])
Run Code Online (Sandbox Code Playgroud)
在其最纯粹的形式中,singledispatch实现依赖于第一个用于标识类型的参数,因此将此功能扩展到实例方法变得棘手.
有没有人有任何关于如何使用(或jerry-rig)此功能以使其与实例方法一起使用的建议?
python single-dispatch instance-method python-3.x python-3.4
当我试图让类装饰器和方法装饰器很好地一起玩时,我遇到了这种行为.从本质上讲,方法装饰器会将某些方法标记为特殊的一些虚拟值,并且类装饰器将在之后出现并稍后填充该值.这是一个简化的例子
>>> class cow:
>>> def moo(self):
>>> print 'mooo'
>>> moo.thing = 10
>>>
>>> cow.moo.thing
10
>>> cow().moo.thing
10
>>> cow.moo.thing = 5
AttributeError: 'instancemethod' object has no attribute 'thing'
>>> cow().moo.thing = 5
AttributeError: 'instancemethod' object has no attribute 'thing'
>>> cow.moo.__func__.thing = 5
>>> cow.moo.thing
5
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么cow.moo.thing = 5不起作用,即使cow.moo.thing很清楚地给我10?为什么cow.moo.__func__.thing = 5有效?我不知道它为什么会这样,但是随机摆弄dir(cow.moo)列表中的东西试图让它起作用突然间,我不明白为什么.
在Ruby中,假设我有一个类Foo允许我对我的大量Foos进行编目.所有Foos都是绿色和球形的,这是一个基本的自然法则,所以我定义了类方法如下:
class Foo
def self.colour
"green"
end
def self.is_spherical?
true
end
end
Run Code Online (Sandbox Code Playgroud)
这让我做到了
Foo.colour # "green"
Run Code Online (Sandbox Code Playgroud)
但不是
my_foo = Foo.new
my_foo.colour # Error!
Run Code Online (Sandbox Code Playgroud)
尽管事实上my_foo是明显的绿色.
显然,我可以定义一个colour调用的实例方法self.class.colour,但是如果我有很多这样的基本特征,那就很难实现.
我也可以通过定义method_missing为任何缺失的方法尝试类来做到这一点,但我不清楚这是我应该做的事情还是丑陋的黑客,或者如何安全地进行(特别是因为我实际上在ActiveRecord下在Rails中,我理解用method_missing做一些Clever Fun Stuff).
你会推荐什么?
似乎Python对实例方法有一些限制.
这对我来说是有问题的,因为我在一个非常面向对象的项目中工作,我在其中引用实例方法,并且使用了深度复制和酸洗.酸洗的事情主要由多处理机制完成.
什么是解决这个问题的好方法?我对复制问题做了一些丑陋的解决方法,但我正在寻找一个更好的解决方案来解决这两个问题.
有没有人有什么建议?
更新:
我的用例:我有一个小事件系统.每个事件都有一个.action属性,指向它应该触发的函数,有时该函数是某个对象的实例方法.
我正在尝试做类似的事情:
def foo(mode= :serial)
if (mode == :serial) then
self.send(:bar, "one_type")
else
self.send(:bar,"second_type",:T5)
end
end
Run Code Online (Sandbox Code Playgroud)
我显然可以这样输入。
但我最近尝试将其扩展为包含这样的第二个功能:
def foo(mode= :serial)
if (mode == :serial) then
self.send(:bar, "one_type")
self.send(:foobar, "one_type",20)
else
self.send(:bar,"second_type",:T5)
self.send(:foobar, "one_type",20,:T5)
end
end
Run Code Online (Sandbox Code Playgroud)
我仍然可以按原样继续,但我对自己想,这里有一个模式,我应该将参数抽象到另一个层中并使这更简单。
所以我想做的是这样的:
arg_arr = [:bar, "one_type"]
arg_arr_2 = [:foobar, "one_type", 20]
if (mode == :serial) then
self.send(arg_arr)
self.send(arg_arr_2)
else
arg_arr << :T5
arg_arr2 << :T5
self.send(arg_arr)
self.send(arg_arr2 )
end
Run Code Online (Sandbox Code Playgroud)
我尝试了一些涉及 .each、.inspect 的其他想法,但没有任何效果(通常的错误是无法将数组转换为字符串,我猜这是指它将数组视为整个函数名称的事实) . 如果我明确说“使用数组元素[0]、[1]等,我可以做到,但这似乎很浪费。
有没有办法在不编写硬编码到参数数量的代码的情况下实现这一目标?
Foo = Class.new
Foo.instance_eval do
def instance_bar
"instance_bar"
end
end
puts Foo.instance_bar #=> "instance_bar"
puts Foo.new.instance_bar #=> undefined method ‘instance_bar’
Run Code Online (Sandbox Code Playgroud)
我的理解是,在对象上调用instance_eval应该允许您为该对象定义实例变量或方法.
但是在上面的示例中,当您在类Foo上调用它来定义instance_bar方法时,instance_bar将成为可以使用"Foo.instance_bar"调用的类方法.很明显,这段代码没有创建实例方法,因为Foo.new.instance_bar导致"未定义的方法'instance_bar'".
为什么instance_eval在此上下文中定义类方法而不是实例方法?
我有以下两种方法:
-(void)authenticateUserToGoogle:(NSString *)userName withPassword:(NSString *)password {
NSString *URLstr = GOOGLE_CLIENT_LOGIN;
URLstr = @"http://www.google.com/ig/api?stock=AAPL";
NSURL *theURL = [NSURL URLWithString:URLstr];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:theURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:100.0];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (!theConnection) {
NSLog(@"COuldn't register device information with Parking Server");
} else {
NSLog(@"Got a connection!!");
NSMutableData *_responseData = [NSMutableData data];
NSLog(@"respone_data = %@",_responseData);
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
NSInteger statusCode = [HTTPResponse statusCode];
if (404 == statusCode || 500 == …Run Code Online (Sandbox Code Playgroud) delegates objective-c nsurlconnection class-method instance-method
我有一个Perl模块文件MyClass.pm,具有非常基本的类定义.
use strict;
use warnings;
package MyClass;
sub new {
my $this = shift;
my $self = {};
bless $self, $this;
return $self;
}
sub displayChar{
my $self = shift;
my $char = shift;
print $char . "\n";
}
1;
Run Code Online (Sandbox Code Playgroud)
我还有一个myClass.pl创建MyClass实例的文件.
#!/usr/bin/perl
use strict;
use warnings;
use MyClass;
my $myClass = MyClass->new();
$myClass->displayChar('a'); # This line works right
my @charArray = ('a', 'b', 'c');
map($myClass->displayChar, @charArray);
Run Code Online (Sandbox Code Playgroud)
当我调用该displayChar方法时,它工作正常,但是当我尝试使用该方法的map函数时,它会给我三次这个错误(每个数组项一次,我猜):
Use of uninitialized value $char in concatenation …Run Code Online (Sandbox Code Playgroud) 我有点不清楚的一点是这些NSMutableArray方法之间的区别:
// Class Method Style
NSMutableData *myMutableDataInstance = [NSMutableData dataWithLength:WholeLottaData];
Run Code Online (Sandbox Code Playgroud)
和
// Instance Method Style
NSMutableData *myMutableDataInstance = nil;
myMutableDataInstance = [[[NSMutableData alloc] initWithLength:WholeLottaData]] autorelease];
Run Code Online (Sandbox Code Playgroud)
在引擎盖下,这里的类方法究竟是什么?它与实例方法有何不同?
干杯,道格
你能帮助我快速理解一个概念,我无法理解从C到Objective-C的转换:
如果我有一个特定的实例方法,如下所示:
-(void)addOwnerNamesObject:(NSString *)n;
{
// ownerNames defined as NSMutableSet
[ownerNames addObject:n];
}
Run Code Online (Sandbox Code Playgroud)
我理解一些事情......
(void)InstanceMethod(Char *nameOfArgument)这是我需要帮助的地方:
NSString是该方法命名的实例n吗?最后......关闭主题
如果你有方法......
-(id)someMethod:(NSString *)pn
{
}
Run Code Online (Sandbox Code Playgroud)
感谢您帮助新手...非常感谢.
instance-method ×11
class-method ×5
ruby ×4
python ×3
objective-c ×2
cocoa ×1
copy ×1
delegates ×1
iphone ×1
map-function ×1
methods ×1
oop ×1
perl ×1
python-3.4 ×1
python-3.x ×1