Python:面对对象成员(2)

核能来袭-成员

一.类的成员

1
2
3
4
5
6
7
8
9
10
class 类名:
# ⽅方法
def __init__(self, 参数1, 参数2....):
# 属性变量量
self.属性1 = 参数1
self.属性2 = 参数2
....
# ⽅方法
def method(self):
pas

在上面代码中__init__method 都属于类的成员方法. 又称为实例⽅方法. 总之这样的东西需要用对象来访问. ⽽而上方的self .属性1 = 参数1 这个代码的含义是给对象设置属性信息. 含义是这个对象的xxx属性是xxxx. 这种东西又被称之为成员变量量或者实例变量量, 再或者被称之为字段. 都是一个意思.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   Province+---------^-------------------------+
^----------+ |
+-----------------+ | |
| | +-----------------+ |obj=Province(北 京 )
| +---------------+ | |
| |country=中 国 |----->#静 态 字 段 | --+-v------------------
| +---------------+ | | name = 北 京 |
| | | | |
| | | +-----------------------+
+-----------------+ | | 类 对 象 指 针 |
| | | | |
| | | +-----------------------+
| | |
| | | obj2 = Province(河 北 省 )
| | |
| def __init__(...) | +------------------------+
| ... | | | name = 河 北 省 |
| def func(...) | | | |
| .. | +^-----+ +----------------------+
| | | 类 对 象 指 针 |
| | | |
| | +------------------------+
| |
| |
| |
| |
+-----------------+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Person:
country = "中国"
#类变量. 不属于对象, 对象可以访问.
#静态变量(静态字段)

def __init__(self, name, num, gender, birthday):
# 成员变量(实例变量)
self.name = name
self.num = num
self.gender = gender
self.birthday = birthday

# 对象来访问(成员方法)(实例方法)
def marray(self, duifang):
print("人会结婚%s" % duifang) #普通字段

alex = Person("李连杰", 10086, "男", "昨天")
alex.country = "澳大利亚" # 注意。 这里和类变量没由一毛钱关系, 给alex单独加一个属性叫country = ”澳大利亚“

wusir = Person("12", 10010, "女", "今天")

print(alex.country) # 澳大利亚 # 拿到的是自己的。成员实例变量 字段
print(wusir.country) # 中国
print(Person.country) # 中国

Person.country# 直接访问静态字段

# 总结:类变量,用类名去操作. 规范.

#静态字段在内存中只保存一份
#普通字段在每个对象中都要保存一份

应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

二.类的成员-方法

  1. 成员方法(实例方法)

  2. 静态方法

  3. 类方法

    1
    2
    3
    4
    5
    6
    class Computer:
    # 实例方法(成员方法)
    def play(self):
    print("我的电脑可以玩⼉")
    c = Computer()
    c.play() # 对象直接去调用实例方法
    1. 成员方法(实例方法:由对象调用;至少一个self 参数;执行普通方法时,自动将调用该方法的对象赋值给self
    2. 类方法:由调用; 至少一个cls 参数;执行类方法时,自动将调用该方法的复制给cls
    3. 静态方法:由调用;无默认参数;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    class Person:

    def __init__(self):
    pass
    # 实例方法需要传递类的对象 self
    def think(self):
    print("人能思考")

    # 静态方法不需要传递对象或者类
    @staticmethod # 静态方法
    def jisuan(a, b):
    print("我来过这里")
    return a + b

    # 类方法: 第一个参数传递的是类名
    @classmethod
    def clsMethod(cls): # cls表示的类
    p = cls() # 可以动态的创建对象.
    print("我是一个类方法", p)


    p = Person()
    p.think()

    Person.think(p)

    # 静态方法的调用:

    c = Person.jisuan(1, 2) # 类名可以访问
    print(c)

    p = Person()
    d = p.jisuan(3, 5) # 用对象也可以访问
    print(d)

    # 记住, 静态的内容用类名访问

    #类方法的调用

    Person.clsMethod() # 类方法默认第一个参数接收的是类名

相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

不同点:方法调用者不同、调用方法时自动传入的参数不同。

三.属性

那么属性就非常简单了,因为Python中的属性其实是成员方法的变种。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


​```python
# ############### 定义 ###############
class Foo:

def func(self):
pass

# 定义属性
@property
def prop(self):
pass
# ############### 调用 ###############
foo_obj = Foo()

foo_obj.func()
foo_obj.prop #调用属性
注意:
1. 方法参数只能有一个self
2. 方法上方要写@property
3. 调⽤用的时候, 我们不需要写括号. 直接当成属性变量来用就可以了了.
4. 这种套路路只能取值. 不能设置值

由属性的定义和调用要注意一下几点:

  • 定义时,在普通方法的基础上添加 @property 装饰器;
  • 定义时,属性仅有一个 self 参数
  • 调用时,无需括号
    ​ 方法:foo_obj.func()
    ​ 属性:foo_obj.prop

四.私有

类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式:

  • 公有成员,在任何地方都能访问

  • 私有成员,只有在类的内部才能方法,私有成员命名时,前两个字符是 下划线 __foo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Tiger:

def __init__(self, name, waibiao, qingzhenglianjiedezuofeng, qingfu, money, fangchan):
self.name = name
self.waibiao = waibiao
self.qingzhenglianjiedezuofeng = qingzhenglianjiedezuofeng
self.__qingfu = qingfu
self.__money = money
self.__fangchan = fangchan

def buy(self):
print("我有%s" % self.__money)
self.__sel()

def __sel(self):
print("我要卖掉%s" % self.__fangchan)


lh = Tiger("alex", "正直", "非常刚正不阿, 666", "小潘潘", 10000000000, 5)
print(lh.qingzhenglianjiedezuofeng)
print(lh.name)
print(lh.waibiao)
lh.buy()
# lh.__sel()
# print(lh.__money)

私有成员和公有成员的访问限制不同

静态字段
  • 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
  • 私有静态字段:仅类内部可以访问;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class C:

name = "公有静态字段"

def func(self):
print C.name

class D(C):

def show(self):
print C.name


C.name # 类访问

obj = C()
obj.func() # 类内部可以访问

obj_son = D()
obj_son.show() # 派生类中可以访问

私有静态字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class C:

__name = "公有静态字段"

def func(self):
print C.__name

class D(C):

def show(self):
print C.__name


C.__name # 类访问 ==> 错误

obj = C()
obj.func() # 类内部可以访问 ==> 正确

obj_son = D()
obj_son.show() # 派生类中可以访问 ==> 错误
普通字段
  • 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
  • 私有普通字段:仅类内部可以访问;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class C:

def __init__(self):
self.foo = "公有字段"

def func(self):
print self.foo  # 类内部访问

class D(C):

def show(self):
print self.foo # 派生类中访问

obj = C()

obj.foo # 通过对象访问
obj.func() # 类内部访问

obj_son = D();
obj_son.show() # 派生类中访问

私有普通字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

class C:

def __init__(self):
self.__foo = "私有字段"

def func(self):
print self.foo  # 类内部访问

class D(C):

def show(self):
print self.foo # 派生类中访问

obj = C()

obj.__foo # 通过对象访问 ==> 错误
obj.func() # 类内部访问 ==> 正确

obj_son = D();
obj_son.show() # 派生类中访问 ==> 错误

方法、属性的访问于上述方式相似,即:私有成员只能在类内部使用

ps:非要访问私有属性的话,可以通过 对象._类__属性名


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!