今天使用 selenium 使用拖拽效果,发现异常的慢.网上一顿搜索,发现解决办法是修改源码控制间隔的属性值..
这样太不友好了.直接全局改了.后来想看能不能外部写一个继承方法来做,看了源码后,还是放弃,水平有限.于是想的通过外部修改.
于是做了一下实验.
代码如下. 备注有返回值
class AAA():
DEP = 0
def get(self):
return self.DEP
print(AAA.DEP) # 0
AAA.DEP = 5 # 修改默认属性
ex_1 = AAA() # 实例化 ex_1
print(ex_1.get()) # 5
AAA.DEP = 10 # 再次修改默认属性
print(ex_1.get()) # 10
ex_1.DEP = 15 # ex_1 修改实例属性
print(ex_1.get()) # 15
AAA.DEP = 12 # 再次修改默认属性
print(ex_1.get()) # 15 被上次实例化修改属性后,类属性不再被修改,即返回 15
ex_2 = AAA() # 实例化 ex_2
print(ex_2.get()) # 12 上段 ex_2 实例化之前前修改的值
AAA.DEP = 20 # 修改原始属性
print(ex_2.get()) # 20
ex_2.DEP = 30
print(ex_2.get())
# 总结,类实例化后若原始属性不被修改 ,均可被外动态修改
后来再次实验,如果被 init 初始化,值也不能被修改了
class AAA():
DEP = 0
def __init__(self):
self.DEP=10 # 被 init 初始化后,不能被修改了
def get(self):
return self.DEP
感觉奇奇怪怪的知识增加了..
这么说,再次使用 selenium 不用使用 time.sleep 来控制了吧. 还没试,先分享下新发现.
1
zagfai 2022-03-25 19:40:35 +08:00
Python 就是太灵活了,所以说做大型项目架构的严谨性更为重要
|
2
alphanow 2022-03-25 19:55:22 +08:00 1
建议读一读 python 官方教程中的 classes 一节。类变量和实例变量并不等价,类变量在所有实例中共享,在通过实例查找变量时实例变量优先于类变量被获取。
把类变量用实例变量覆盖的方式不如通过子类覆写类变量的方式安全。 |
3
Nitroethane 2022-03-25 19:59:59 +08:00 via iPhone 2
你是把类变量喝对象变量混淆了。看这个 https://stackoverflow.com/a/5690920
|
4
mangoDB 2022-03-25 20:18:12 +08:00
楼主看下 3# 答案,解释很清晰。
|
5
Dganzh 2022-03-25 20:36:04 +08:00
好像也没啥问题,实例属性覆盖类属性了。
主要是 Python 太灵活,ex_1.DEP = 15 ,这样可以动态创建实例属性。 |
6
ClericPy 2022-03-25 21:00:16 +08:00
|
7
rrfeng 2022-03-25 21:21:30 +08:00 via Android
上面解释很清晰了。但是可以在外面改类内的变量就很奇怪…
|
8
imn1 2022-03-25 21:22:10 +08:00
只会在同一个引用链条上起作用,分别两个地方引用,改变其中一个,另一个还是原值,相当于作用域不同
或者试试外部改变后,reload 一次看看 “总结,类实例化后若原始属性不被修改 ,均可被外动态修改” 这句就不评价了,前面几楼都讲太多了 AAA.DEP=30 a=AAA() a.DEP=20 print(a.DEP) print(AAA.DEP) |
9
imn1 2022-03-25 21:30:22 +08:00
@rrfeng #7
因为 python 几乎全部变量都是引用,只有 int/float/complex/string 等少量类型不是 外部改变实际上只是改变了引用的指向,我是这样理解的,但也不知道对不对 反正我也不知道如何用原生语法定义一个不可变(只读)的常量 |
10
JeffGe 2022-03-25 21:43:59 +08:00 via Android
@imn1 不用几乎,Python 里面所有的变量赋值都是共享对象传递
https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing |
11
beastk 2022-03-26 00:07:10 +08:00 via iPhone
和调用顺序有关,本来就是这样
|
12
lux182 2022-03-26 01:27:36 +08:00
个人感觉大型项目还是不敢用 python ,如此灵活的语法太容易写出致命 bug
|
13
LeeReamond 2022-03-26 02:35:40 +08:00 2
@lux182 解决方案:招募正经程序员
|
14
vicalloy 2022-03-26 07:51:40 +08:00
monkey patch 这 python 里面也算是挺常规的操作。
|
15
est 2022-03-26 09:19:00 +08:00
这还不算啥,你还可以在运行中改方法、改方法的参数,改方法内部的变量。
|
16
mongodb 2022-03-26 09:32:53 +08:00 2
Python 太灵活是真的,但拜托你们也把文档读完啊……
|
17
llsquaer OP @est 之前也干过运行中从外部改方法..但是改的时候都是实例化后修改的实例方法.. 现在是突然想到直接改类默认属性的想法..所以才实验一番..
其实 2 楼 3 楼已经说明了原因.. 只是忘记了在类变量内部搜索方式了..因为平时很少这么用的场景.. 实际上实例化后也是可以获取到初始属性的 使用 __class__ 方法 |
18
llsquaer OP |
19
kilasuelika 2022-03-27 10:29:49 +08:00
我寻思这其实有点像 C++中的静态变量?同样可以在没有实例化的情况下修改:
``` #include <iostream> struct AAA { static int DEP; int get()const { return this->DEP; }; }; int AAA::DEP = 0; int main() { AAA::DEP = 5; std::cout << AAA::DEP << std::endl; //5 AAA a; std::cout << a.get() << std::endl; //5 a.DEP = 15; std::cout << a.get() << std::endl; //15 } ``` 不过有个区别是`this->DEP`与`DEP`是同一个变量,所以这里在 C++中是不行的: ``` AAA.DEP = 12 # 再次修改默认属性 print(ex_1.get()) # 15 被上次实例化修改属性后,类属性不再被修改,即返回 15 ``` C++里面后一句必然是 12 。 |
20
DOLLOR 2022-03-27 15:29:11 +08:00
@kilasuelika
我写 python 从来不用 class ,也是觉得不可思议。 python 的 self.xxx ,有可能指向静态成员(类变量),也可能指向实例成员(对象变量)。 如果实例化的对象时没有初始化实例成员,就会使用静态成员作为默认值。 |
21
kilasuelika 2022-03-27 23:29:55 +08:00 via Android
@DOLLOR 我也是第一次听说 python 中的这种情况。感觉这个特性有点容易导致问题🤣
|
22
neoblackcap 2022-03-28 02:40:50 +08:00
如果多写 Python 就会习惯了,这设计就是这样的。甚至还有用这个特性去替代单例模式。
|
23
lanlanye 2022-03-28 03:44:15 +08:00 via iPhone
所以不建议水平不够的人写 Python ,更不建议和水平不够的人合作 Python 项目
语言没有约束,就只有靠程序员自己去约束了 |
24
hhhhhh123 2022-03-28 10:04:23 +08:00
我没太看懂你想要啥 你可以试试这个
class AAA: DEP = 0 def get(self): return self.DEP def set(self, x): return self.DEP + x print(AAA().set(12)) # 12 print(AAA().get()) # 0 |