我来自C ++和Java环境,刚刚开始学习Python,因此是这个问题。 The Zen of Python中有一个引号:
显式优于隐式。
那么,有没有一种方法可以一次在Python中显式地声明静态和/或非静态属性?
例如(不完整的python代码):
class BasicClass():
# Explicit declaration of a attribute shared through the class and instances
x = 0
# Explicit declaration of a attribute that I would like to be owned only by the class
static:
y = 10
# Explicit declaration of a attribute that I would like to be owned by every instance individually
non_static:
z = 0
def __init__(self, x, z):
self.x = x
self.z = z
a = BasicClass(1, 2)
b = BasicClass(3, 4)
尽管Python中不存在'static'和'non_static'关键字,但这是我想要实现的行为:
x
以及BasicClass.x
和a.x
访问b.x
属性。是所有不同的实例。y
属性是“静态”的,因此应仅由BasicClass
实例拥有(并通过该实例访问)。
a.y
可以作为对BasicClass.y
的引用。z
属性是“非静态的”,因此应通过a.z
和b.z
(二者是不同的实例)进行访问,并且不能直接通过{{1 }},因为它不能具有此属性。我认为第一个期望的行为是实际发生的事情。
关于第二个,很明显为什么BasicClass
这样的属性很重要并且很受欢迎。
关于第三个问题,我知道可以沿着类的方法声明一个属性。但是可以一次全部声明吗?如果没有,为什么?再说一次,如果不是,这样会更好吗?
显式声明y
函数内部的所有内容可能会遇到问题,因为我希望不要初始化属性。还是这是C ++ / Java的偏见?
答案 0 :(得分:1)
Python没有“静态”属性的概念,而不是C ++定义它们的方式。
相反,在实例上执行Python属性查找需要执行以下步骤;如果步骤成功,则确定结果,并跳过进一步的步骤:
property
object。__dict__
命名空间,请检查其中的属性__getattr__
方法,则会调用它以查看它是否可以提供结果。就是这样;从最基本的角度来说,实例和类是分层的名称空间。没有声明属性,它们之所以存在是因为它们只是被使用。
您可以使用type hinting帮助诸如IDE和静态类型验证器之类的工具检查类型正确性,并且您可以使用此类提示来声明您的类将使用带有指定的类型,例如:
from typing import ClassVar
class BasicClass:
x: int = 0 # instance and class attribute, with a default value for the class
y: ClassVar[int] = 10 # explicitly a class attribute
z: int # instance attribute
def __init__(self, x: int, z: int) -> None:
self.x = x
self.z = z
但是Python运行时不会强制执行有关可以在何处设置哪些属性的任何规则。但是,当您在将y
的实例上设置BasicClass
的代码上运行它时,像mypy这样的静态类型检查器将引发错误:
$ tail -n 2 thdemo.py # two lines added to the above example
a = BasicClass(42, 81)
a.y = 117
$ mypy thdemo.py
thdemo.py:14: error: Cannot assign to class variable "y" via instance
如果您不使用类型提示,那么您就不必“声明”属性。属性只是“是”,您可以使用它们,也可以不使用。 Python假设我们都是成年人,可以在必要时编写单元测试,否则几乎完全是动态的。这为您提供了很大的灵活性和力量,可以执行在C ++或Java中更加困难和冗长的工作。
答案 1 :(得分:0)
Python很简单,不需要静态关键字。
在类声明中分配的变量是类变量或静态变量,而在类方法内部的变量是实例变量。
class Employee:
empName = 'Vicky' #class variable
def __init__(self, age, id):
self.age = age #instance variable
self.id = id #instance variable
one = Employee(21, 1)
two = Employee(30, 2)
print(one.empName) # prints "Vicky"
print(one.age) # prints 21