2016-09-23 27 views
20

Tôi đang cố gắng kế thừa từ lớp cơ sở .NET trừu tượng bằng Python (2.7) bằng Python.NET (2.1.0). Tôi là một n00b Python nhưng từ những gì tôi hiểu ...Cách kế thừa từ một lớp cơ sở trừu tượng được viết bằng C#

Dưới đây là những gì tôi cố gắng làm trong chỉ Python và đó hoạt động tốt:

import abc 

class Door(object): 
    __metaclass__ = abc.ABCMeta 

    def open(self): 
     if not self.is_open(): 
      self.toggle() 

    def close(self): 
     if self.is_open(): 
      self.toggle() 

    @abc.abstractmethod 
    def is_open(self): 
     pass 

    @abc.abstractmethod 
    def toggle(self): 
     pass 

class StringDoor(Door): 
    def __init__(self): 
     self.status = "closed" 

    def is_open(self): 
     return self.status == "open" 

    def toggle(self): 
     if self.status == "open": 
      self.status = "closed" 
     else: 
      self.status = "open" 

class BooleanDoor(Door): 
    def __init__(self): 
     self.status = True 

    def is_open(self): 
     return self.status 

    def toggle(self): 
     self.status = not (self.status) 

Door.register(StringDoor) 
Door.register(BooleanDoor) 

Bây giờ, tất cả tôi đã làm là để thay thế trừu tượng lớp cơ sở Door bởi một C# đại diện:

namespace PythonAbstractBaseClass 
{ 
    public abstract class Door 
    { 
     public virtual void Open() 
     { 
      if (!IsOpen()) 
       Toggle(); 
     } 

     public virtual void Close() 
     { 
      if (IsOpen()) 
       Toggle(); 
     } 

     public abstract bool IsOpen(); 
     public abstract void Toggle(); 
    } 
} 

Loại bỏ cửa từ phần Python và nhập khẩu nó từ lắp ráp NET thay vào đó, tôi kết thúc với điều này:

import clr 
import abc 
from PythonAbstractBaseClass import Door 

class StringDoor(Door): 
    def __init__(self): 
     self.status = "closed" 

    def is_open(self): 
     return self.status == "open" 

    def toggle(self): 
     if self.status == "open": 
      self.status = "closed" 
     else: 
      self.status = "open" 

class BooleanDoor(Door): 
    def __init__(self): 
     self.status = True 

    def is_open(self): 
     return self.status 

    def toggle(self): 
     self.status = not (self.status) 

Door.register(StringDoor) 
Door.register(BooleanDoor) 

Nhưng điều này không thành công với thông báo lỗi sau:

Door.register(StringDoor) 
AttributeError: type object 'Door' has no attribute 'register' 

Từ những gì tôi hiểu về abc.ABCMeta, metaclass này góp phần phương pháp register(). Có vẻ như các lớp C# trừu tượng không có cùng một metaclass. Thay vào đó, chúng đi kèm với metaclass CLR Metatype mà rõ ràng là không cung cấp register().

Nhưng nếu tôi thả các cuộc gọi đến register(), trên instantiating một trong những lớp học có nguồn gốc, tôi nhận được thông báo lỗi

sdoor = StringDoor() 
TypeError: cannot instantiate abstract class 

Có cách nào để kế thừa từ một lớp .NET trừu tượng hay là này một thiếu đặc tính?

Cảm ơn trước,

Henning

+0

@TomHunter đây là các cuộc thảo luận ban đầu trong danh sách gửi thư: https://mail.python.org/pipermail/pythondotnet/2016-September/001813.html – denfromufa

+0

Xin chào @denfromufa, có vẻ như bạn ar e nói rằng bạn không thể kế thừa từ một lớp trừu tượng .NET sử dụng Python và Python.Net .. xin vui lòng bạn có thể xác nhận? Cảm ơn –

+0

@TomHunter Tôi không nghĩ rằng tính năng này đã được triển khai trong pythonnet. Vui lòng gửi yêu cầu tính năng trong trình theo dõi vấn đề. – denfromufa

Trả lời

8

Bạn không thể tạo một thể hiện mới của một lớp trừu tượng trong C#. nói rằng, Python sẽ yêu cầu bạn sử dụng thanh ghi, vì nó sẽ không cho phép bạn sử dụng lớp thừa kế của bạn mà không cần đăng ký nó, trừ khi bạn khởi tạo nó.

nếu bạn muốn kế thừa từ một lớp trừu tượng C# trong python, bạn sẽ phải tự viết biểu diễn của lớp đăng ký trong python tại lớp C# của bạn, do đó sẽ đăng ký cuộc gọi trừu tượng của bạn và có thể kế thừa từ nó .

tôi sẽ đề nghị trang web này để dễ dàng giúp bạn chuyển đổi giữa các mã nếu cần phải:

https://www.varycode.com/converter.html

5

Tôi hoàn toàn không quen thuộc với pythonnet (hoặc python nói chung cho rằng vấn đề), nhưng tôi tò mò nếu một cái gì đó như thế này có thể làm việc:

import clr 
import abc 
from PythonAbstractBaseClass import Door 

class DoorWrapper(Door): 
    __metaclass__ = abc.ABCMeta 

class StringDoor(DoorWrapper): 
    ... 

class BooleanDoor(DoorWrapper): 
    ... 

DoorWrapper.register(StringDoor) 
DoorWrapper.register(BooleanDoor) 
Các vấn đề liên quan