我有一个继承自字典的类,以便添加一些自定义行为 - 在这种情况下,它将每个键和值传递给一个函数进行验证.在下面的示例中,"验证"只是打印一条消息.
字典的分配按预期工作,每当项目添加到字典时打印消息.但是当我尝试使用自定义字典类型作为__dict__类的属性时,属性赋值又将键/值放入我的自定义字典类中,以某种方式设法在完全绕过时将值插入字典中__setitem__(以及其他方法我已定义可能添加密钥).
自定义词典:
from collections import MutableMapping
class ValidatedDict(dict):
"""A dictionary that passes each value it ends up storing through
a given validator function.
"""
def __init__(self, validator, *args, **kwargs):
self.__validator = validator
self.update(*args, **kwargs)
def __setitem__(self, key, value):
self.__validator(value)
self.__validator(key)
dict.__setitem__(self, key, value)
def copy(self): pass # snipped
def fromkeys(validator, seq, v = None): pass # snipped
setdefault = MutableMapping.setdefault
update = MutableMapping.update
def Validator(i): print "Validating:", i
Run Code Online (Sandbox Code Playgroud)
使用它作为__dict__类的属性产生我不理解的行为.
>>> d …Run Code Online (Sandbox Code Playgroud) 我正在开发一个库,它实现了一个适用于任何有序数据类型的数据结构 - 一个范围集.当你允许正负无限时,许多操作(如反转)会变得有趣.
一个目标是让datetime对象与该模块一起使用,并且在使用非数字对象支持infinity时,我创建了INFINITY和NEGATIVE_INFINITY:
class _Indeterminate(object):
def __eq__(self, other):
return other is self
@functools.total_ordering
class _Infinity(_Indeterminate):
def __lt__(self, other):
return False
def __gt__(self, other):
return True
def __str__(self):
return 'inf'
__repr__ = __str__
@functools.total_ordering
class _NegativeInfinity(_Indeterminate):
def __lt__(self, other):
return True
def __gt__(self, other):
return False
def __str__(self):
return '-inf'
INFINITY = _Infinity()
NEGATIVE_INFINITY = _NegativeInfinity()
Run Code Online (Sandbox Code Playgroud)
不幸的是,当在cmp()操作的左侧时,这对datetime对象不起作用:
In [1]: from rangeset import *
In [2]: from datetime import datetime
In [3]: now = datetime.now()
In [4]: cmp(INFINITY, now)
Out[4]: 1 …Run Code Online (Sandbox Code Playgroud) 在Yii框架的本教程中 http://www.yiiframework.com/doc/guide/1.1/en/basics.controller#action
我想把我的动作从一个控制器放到一个单独的动作文件中,并按照说明"创建一个Action类"
这是我的动作类文件
class LoginAction extends CAction
{
private $contents = array();
public function run(){
$loginmodel = new LoginForm;
//answer ajax validating request
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form'){
echo CActiveForm::validate($loginmodel);
Yii::app()->end();
}
//collect user input data to do login
if(isset($_POST["LoginForm"]))
{
$loginmodel->attributes = $_POST["LoginForm"];
// validate user input and redirect to the previous page if valid
if($loginmodel->validate() && $loginmodel->login()){ //<--invoking here the login and validate function
$this->redirect(Yii::app()->user->returnUrl);
}
}
$this->contents["loginmodel"] = $loginmodel;
$this->render('index',$this->contents);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的控制器中
class SandboxController extends Controller{
public …Run Code Online (Sandbox Code Playgroud) 我是Python的新手,也是OOP的新手.我有一个错误"...instance has no attribute '__getitem__'",我知道我创建的对象不是列表.我怎样才能成为列表对象.这是类文件:
#!/usr/bin/python -tt
import math, sys, matrix, os
class Point:
'Class for points'
pointCount = 0
def __init__(self, x, y, z):
'initialise the Point from three coordinates'
self.x = x
self.y = y
self.z = z
Point.pointCount += 1
def __str__(self):
'print the Point'
return 'Point (%f, %f, %f)' %(self.x, self.y, self.z)
def copyPoint(self, distance):
'create another Point at distance from the self Point'
return Point(self.x + distance[0], self.y + distance[1], self.z + distance[2]) …Run Code Online (Sandbox Code Playgroud) 我正在使用Enterprise Architect制作UML类图并用它生成PHP5代码.使用它,可以为属性创建getter和setter,在代码中看起来像这样(只显示相关的行):
private $id;
public function getId()
{
return $this->id;
}
/**
*
* @param newVal
*/
public function setId($newVal)
{
$this->id = $newVal;
}
Run Code Online (Sandbox Code Playgroud)
我想使用魔术方法__get($property)而__set($property, $value)不是每个属性的单独方法.是否可能,如果可能,怎么样?
对于getter来说,它看起来像这样:
public function __get($property)
{
switch ($property) {
case 'id': return $this->id; break;
default: return null;
}
}
Run Code Online (Sandbox Code Playgroud) OBS:我在这里直接编码,因为我的代码要复杂得多.
如果我编码:
class SuperFoo {
public function __get($name) {
return $this->$name;
}
public function __set($name, $value) {
$this->$name = $value;
}
}
class Foo extends SuperFoo {
private $bar = '';
}
$foo = new Foo();
$foo->bar = "Why it doesn't work?";
var_dump($foo);
Run Code Online (Sandbox Code Playgroud)
结果是:
object(Foo) {
["bar":"Foo":private]=>
string(0) ''
}
Run Code Online (Sandbox Code Playgroud)
而不是:
object(Foo) {
["bar":"Foo":private]=>
string(20) 'Why it doesn't work?'
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我不想使用数组来保存属性,因为我需要将它们声明为单独的私有成员.
我不确定在PHP 中使用__get和__set方法有什么价值.
这是在数组中设置值的代码.
class myclass {
public $sotre = array();
public function __set($arraykey,$value){
echo 'Setting '.$arraykey.' to '.$value;
$this->store[$arraykey] = $value;
}
}
$obj = new myclass;
$obj->a = 'arfan';
Run Code Online (Sandbox Code Playgroud)
这是另一个代码.
class myclass {
public $sotre = array();
public function setvalue($arraykey,$value){
echo 'Setting '.$arraykey.' to '.$value;
$this->store[$arraykey] = $value;
}
}
$obj = new myclass;
$obj->setvalue('a','arfan');
Run Code Online (Sandbox Code Playgroud)
这两个函数都做同样的事情.
代码使用__get/ __setmagic方法:
class myclass {
public $store =
array(
'a'=>'arfan',
'b'=>'azeem',
'c'=>'hader'
);
public function __get($arraykey){ …Run Code Online (Sandbox Code Playgroud) 主语
例子:
MyList(object):
def __init__(self, list_to_be_wrapped):
self._items = list_to_be_wrapped
def __getattr__(self, item):
return getattr(self._items, item)
Run Code Online (Sandbox Code Playgroud)
然后
MyList([1, 2, 3])[-1]
Run Code Online (Sandbox Code Playgroud)
将提高: TypeError: ‘MyList’ object does not support indexing
尽管:
MyList([1, 2, 3]).pop()
Run Code Online (Sandbox Code Playgroud)
将完美运行(pop将被拦截__getattr__并重定向到_items)
在我看来,__getattr__考虑到“通过组合而不是继承实现自己的容器类型”的情况,拦截魔术方法会非常有帮助。为什么python不支持这种“拦截”?
我不想在使用时测试钥匙的类型__setitem__.但奇怪的是,当使用多个密钥时,我发现某些代码被省略了.这是我的测试类:
class foo():
def __init__(self):
self.data=[[1,2],[3,4],[5,6]]
def __getitem__(self, key):
return self.data[key]
def __setitem__(self, key, value):
print('Key is {0}, type of key is {1}'.format(key,type(key)))
self.data[key] = value
f = foo()
Run Code Online (Sandbox Code Playgroud)
使用一把钥匙就可以了:
>>>f[1] = [0,0]
Key is 1, type of key is <class 'int'>
>>>f[1]
[0, 0]
Run Code Online (Sandbox Code Playgroud)
当使用两个键时,结果是正确的,但为什么没有打印出来
>>>f[1][1] = 100
>>>f[1][1]
100
Run Code Online (Sandbox Code Playgroud)
我是python的新手,任何建议都会赞赏!
该属性__dict__应包含用户定义的属性.但是如果我们打印__dict__一个空类,我也会得到:
__module__
__dict__
__weakref__
__doc__
Run Code Online (Sandbox Code Playgroud)
其中Python在__dict__属性中预先填充了类对象类型.
现在,__base__并且__class__也Python中定义的类的对象类型的属性,但不包括在__dict__.
是否有任何规则指定哪个dunder属性包含在一个对象中__dict__哪个不包含?
magic-methods ×10
python ×6
php ×4
oop ×2
attributes ×1
class ×1
comparison ×1
containers ×1
getattr ×1
indexing ×1
inheritance ×1
list ×1
object ×1
python-3.x ×1
uml ×1
yii ×1